Does anyone here use their CopyNES in Linux? I've had one for a while and never really got around to using it.
There's a few ways to do it involving varying levels of virtualization and emulation (full virt, wine, dosemu, etc), but I'd like to know what other people are doing.
I've though about re-writing the qbasic program in some more recent language, but I'm kinda busy (mainly lazy and hating BASIC).
I had to dump the Parallel version for the USB version for similar reasons. New Macs don't have parallel ports. From their it's easy to port over, I've got it working natively and through Parallels.
The irony of the parallels in your post made me LOL.
Hi AtariMike,
You sound like you are in a similar boat to myself, I have also considered rewriting the software for Linux. I was a little worried that I would wreck the thing though
Well, in answer to your question, I have successfully been using the parallell version of the CopyNES in linux by running in it windows in VMWare. Probably not all that helpful since running in VMWare is practically like running Windows on the hardware.
I had to use the parport (somewhat older, but allows for real control & development with the parallel port) kernel option for the parallel port device even for it to work in VMWare. I also had to play arround switching the BIOS setting in the VMWare image for the Parallel port, but I asume you would need to do that on a regular windows box too.
I never tried it in Wine. The software/hardware combo just seemed to fragile for me to believe it would work, and now unfortunately, I fried by serial CopyNES and replaced it with a USB one. This one seems to work with no trouble in my VMWare image.
I am reconsidering rewriting the code for the USB version now, as the source is provided, and the component they use for USB communications has a linux version, so it probably wouldn't be too bad.
Has anyone had any luck using the USB CopyNES in Linux (with Wine or otherwise)? I've done a little bit of experimenting and found out:
1. The USB CopyNES uses a USB to serial adapter (FT2232C).
2. Linux recognizes the adapter and maps it to a serial port (/dev/ttyUSB0 and /dev/ttyUSB1)
3. USB CopyNES software appears to run fine with Wine; but it is not programmed to address a serial port directly, only through USB (via ftd2xx.dll).
4. The parallel port CopyNES software will not work, because it is programmed for a parallel port and not a serial port.
I figure if the USB CopyNES program could be programmed to address the CopyNES as a serial port rather than USB (via ftd2xx.dll), it could be used in Wine without any problems.
what does ftd2xx.dll do and is that a windows file or a file of copynes?
i do not have a copy nes and have no experience with it.
i would be interested getting one if it worked with linux and mac natively. (no wine). if copynes uses a usb serial port, then it should be possible to use on any OS with usb ?
matt
The FT2232 isn't a serial adapter, it's a custom serial UART/parallel FIFO interface, basically FTDI took their serial (232) and parallel (245) chips and combined them into the 2232. The DLL is absolutely necessary to use the chip unfortunately.
hmmm
then what is dev/ttyUSB0 and /dev/ttyUSB1 as famitek suggested ?
scanty already made a port of the copynes parallel software to linux. I THINK I have a copy of it somewhere...
Edit: found it.
http://www.sendspace.com/file/tqpc3i
LN
thanks for the link. i was interested in a usb version. i do not have a parallel port ( not missing it, deprecated).
i did try that link. need javascript to download? rrrrrrriigghhttt :S
thanks
matt
mattmatteh wrote:
hmmm
then what is dev/ttyUSB0 and /dev/ttyUSB1 as famitek suggested ?
It does this because the chips can be talked to as a serial device with a driver, and Linux apparently has the [virtual COM port] driver built in. Here's a 3rd-party library to use the more direct "bitbang" mode however:
http://www.intra2net.com/en/developer/libftdi/index.php
I don't believe that an app built for the old parallel copynes would work directly with the new usb copynes without modification.
The new usb copynes has a dataport and a control port which are both treated as seperate serial ports when plugged in through the usb->serial driver in linux. I *believe* the old one used the parallel port to do both data and control combined.
the usb to serial driver isn't neccessarily built in, you may need to enable it in the kernel configuration. You need the usb serial kernel module and the ftdi sdio driver for it enabled in the kernel.
On my machine, this creates /dev/USBtty0 and /dev/USBtty1 when the usb is plugged in.
I'm trying to do the exact same thing. I've got Ubuntu running the 2.6.24 kernel and a USB CopyNES. Here's what I have so far:
1. I have confirmed from this page that newer 2.6.x kernels use the ftdi_sio driver that supports the FT2232C chip that is in the USB CopyNES. I'm hoping to figure out how to make this all work without resorting to libftdi.
2. When I connect my CopyNES to my Linux box the ftdi_sio driver is loaded automatically and both UARTs are detected. The first one is bound to /dev/ttyUSB0 and the second is bound to /dev/ttyUSB1. Here's the dump from lsusb -v:
Code:
Bus 002 Device 006: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x0403 Future Technology Devices International, Ltd
idProduct 0x6010 FT2232C Dual USB-UART/FIFO IC
bcdDevice 5.00
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 55
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 2
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 2
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
and the output from /var/log/syslog:
Code:
Mar 2 12:32:47 mycroft kernel: [254659.999433] usb 2-1: new full speed USB device using uhci_hcd and address 6
Mar 2 12:32:47 mycroft kernel: [254660.257997] usb 2-1: configuration #1 chosen from 1 choice
Mar 2 12:32:47 mycroft kernel: [254660.260911] ftdi_sio 2-1:1.0: FTDI USB Serial Device converter detected
Mar 2 12:32:47 mycroft kernel: [254660.260930] /build/buildd/linux-2.6.24/drivers/usb/serial/ftdi_sio.c: Detected FT2232C
Mar 2 12:32:47 mycroft kernel: [254660.260987] usb 2-1: FTDI USB Serial Device converter now attached to ttyUSB0
Mar 2 12:32:47 mycroft kernel: [254660.265623] ftdi_sio 2-1:1.1: FTDI USB Serial Device converter detected
Mar 2 12:32:47 mycroft kernel: [254660.265643] /build/buildd/linux-2.6.24/drivers/usb/serial/ftdi_sio.c: Detected FT2232C
Mar 2 12:32:47 mycroft kernel: [254660.265692] usb 2-1: FTDI USB Serial Device converter now attached to ttyUSB1
3. I was looking at the source code for the CopyNES host app and trying to get a simple demo program running to confirm that the CopyNES is up and running. The CopyNES host app is just a windows app that sends different commands to the CopyNES with the correct data. There is a command called "CMD_NESINFO" that writes the by 0xA1 on the first UART and then reads back the version string from the first UART. Here's the code but it doesn't seem to work. It hangs during the read loop.
4. I think maybe I'm not initializing the CopyNES correctly...I mentally stepped through the CopyNES source code to see where it initializes the chip but since I don't have the source code for all of the FT_* functions provided by the windows ftd2XX.dll, I can't be 100% sure I'm doing everything correct.
Does anybody have a doc on the protocol for the CopyNES? How about more info on how the two UARTs are hooked up to the CopyNES? Also, is there a correct procedure for powering on the NES and connecting the USB cable? I've just be plugging in the NES, turning it on, then connecting the USB cable.
I could easily reverse the entire protocol from the source code for the windows host app. I was hoping that somebody would have a more detailed doc though.
I think it is time to look at the data sheet for the FT2232 chip too.
So it looks like using libftdi is the way to go. That means that you need to unload the ftdi_sio module from your kernel like so:
Code:
rmmod ftdi_sio
then use the libftdi library to talk to the CopyNES. I'll have a demo app in just a few minutes.
I don't see offhand the problem with your code, but I'm pretty sure the kernel driver works fine, and it looks like it is set up right from your posted info.
I have been able to get the internal copynes version and bios version using this driver and put the thing into play mode. Some commands need to be sent to the control port (I think control is /dev/USBtty1 but I might be misremembering) and some to the data port. I can post some sample code in a few hours when I get home.
Will you post your code? I had to do the soldering of the CopyNES myself and I may have screwed something up (e.g. cold solder joint, etc).
NOTE: I've never run my CopyNES using a windows machine. Do I have to upload an EEPROM image to it or anything? Basically, I followed the desoldering/soldering instructions to install the thing and then hooked it up to my Linux box. Do I need to go through the full install process on a windows box to initialize my CopyNES?
As far as I know there is no special initialization required first on the copynes side. It should run immediately when you plug it in to the linux box.
Here is the code:
http://pastebin.com/meaf9cec
Now, I know the first character always gets screwed up in this sample (don't know why yet, but it could be a quirk in the actual unit)
the code should basically output a version string read from the copynes.
I am working on an actual program, but you know.. I'm slow
Sorry I meant to add that:
even though only the data port is being used here, the program will fail if you don't open both ports.
So that's what I was doing wrong! Two things:
1. I wasn't opening both devices.
2. I wasn't using the O_NDELAY option.
Well, I took your code and tweaked it a little and now it works perfectly. Here's
the code
So now that we know how to talk to this thing. The next big hurdle is to be able to toggle the RTS and DTS lines properly on the second serial port so that we can execute the reset functions properly. Every other command seems to require resetting the CopyNES into various modes (e.g. play mode, copy mode, etc).
As soon as we get that down, we'll have all the initialization and control stuff working. At that point, I say we go ahead and start a proper open source libCopyNES project on google code or sourceforge.
I started looking at the whole plugin loading stuff and the protocols used for various functions. If you look at the USBBIOS4.ASM file, it describes the whole protocol used for read/write to CPU/PPU memory and executing code. Knowing that, the commands for dump cart start to make sense. First it loads the "clear" plugin into CPU memory which sets the RAM to 0xFF. It then resets the CopyNES into copy mode, loads the plugin specified by the user (this is cart specific) and then it runs the plugin which is just a fragment of 6502 code that dumps out all of the data stored in the cart out over the data channel. When the dump is done, it resets the CopyNES again.
Getting all of this code up and running in a cross platform lib/tool should not be hard. I'm thinking a libCopyNES C library that handles all of the functions and a front end tool written in C# (mono gtk#) would be the best approach.
It looks like there are virtual com port (VCP) drivers for Windows, Linux (ftdi_sio that we're using), and Mac OS X. So if we can get everything working using the serial port, then libCopyNES combined with the VCP drivers should work on all systems.
toggling the control lines works fine as well using the standard POSIX functions:
(i have built this part):
http://pastebin.com/mc4b978a
I have been working on a proper program.. but I'm slow.
New version of
the code.
It's a sample command line app that supports two commands: "version" and "play". If you run it with the "version" option, it gets the version string from the CopyNES and writes it out to the console.
If you run it with the "play" option, it correctly fiddles with the RTS/DTS lines on the second serial port to reset the CopyNES into play mode which plays whatever cart you have in your NES. It then waits for you to press enter. When you do, it resets the CopyNES back into copy mode.
So I now have the reset function working perfectly. I think it is time to create a proper libCopyNES project now.
I have actually started on this project, but I made it unneccessarily complicated (as I always do)
I am trying to do asynchronous communication rather than the sleep() junk that the current source does.
so I'm currently stuck on some standard C problems.
I am certainly willing to share / post what I have so far.
Sure, post it. I know how to use fd sets and signals to do async I/O. If you post the whole thing, I can clean it up into a proper automake type package (i.e. ./configure, make, make install) and see if I can help you with the async I/O.
We need a project page. Sourceforge?
Here's
new code. Same as before except that it correctly detects whether the NES is on in the init_port function.
Hey, I tried to create a new sourceforge project for it, but it will take awhile before it gets approved. If you want, pm me and I will email you the package. It already has autoconf stuff built in.
You are so much faster at this than I am lol, I have been working on this thing for a while but I didn't think it was far enough along to create a project yet.
It is currently not in a working state. I The current problem is that the change_recv_size function doesn't switch the receiving mode from size based to terminator based receiving (like I said it's unneccessrily complicated)
feel free to hack the heck out of it and pull out all the asynchronous junk if you like, it's kinda a waste anyway considering it's serial communication
I'll see what I can do. I think the simplest solution is to just use FD sets to implement async communication. That way, the code that I've been publishing here doesn't change all that much. The read loops are transformed into signal callbacks and FD set tests to see which fd woke up the application and then reading the data back.
I honestly don't think that async really buys you much. It's more complicated and this application is very synchronous in nature. You click a button to execute a command and it does it. Async is really only useful when you get random events you have to handle or if you have really long jobs that you're waiting on and you don't want to poll.
I'm most interested in getting this to work because I hate how all of these hacker tools are windows only. Also because I'm working on an ethernet adapter that plugs into the NES expansion port and I need a tool like this to explore the expansion port stuff.
I'm 99% sure I have a workable ethernet adapter design using the Microchip ENC28J60 chip. The plan is to use the controller port bits that go to/from the expansion port to send/receive data over the SPI interface to the ethernet chip. It won't be crazy fast, but it will be fast enough to make networked games. I'm hoping to write the world's first 8-bit MMORPG
I'm now in the ethernet adapter driver writing phase and need to get this CopyNES working. I haven't used Windows in over 5 years so I'm dedicated to making this work on Linux.
Yeah, I'l admit to having alterior motives.. I already wrote the networking code from another (tcpip based) project, and I wanted to see if I could make it work with the serial port.. you can kinda tell by the "fake synchronize" code that it doesn't exactly *need* asynchronous code. It got a bit outa hand.
It would definately be better to keep it simple asuming were trying to make a *useful* project, but since I found myself pasting you code from there more than once I thought it would help if you just had the whole thing
Yep, you're right about the complexity. You've written a ton of code. I'm thinking that we should start over from scratch. I've only written a hundred lines of code or so and I almost have full control over the CopyNES.
This doesn't mean what you've written is useless. I'm thinking that a simple libCopyNES would sit underneath all of your other stuff that is in that library. That way it would still be useful to you.
the code from the serial project that Lord Nightmare posted
http://www.sendspace.com/file/tqpc3i
looks like it would be really helpful for the cart dumping part.
Quote:
I'm thinking that we should start over from scratch
Agreed. I think everything useful (to copynes) out of that package is already in your file.
There is a ton of code there, but most of it is recycled.
Let me know if you are going to open a libCopyNES source code / google code project. I would like to help further too if there are some functions you don't feel like implementing, let me know.
here's the first release...it just supports open/close, reset, version for now...
I spent all my time trying to figure out autotools...
http://www.linuxprogrammer.org/
I use dreamhost which allows me to have my own subversion server. You can get the latest code from:
Code:
svn co http://code.linuxprogrammer.org/libcopynes/trunk
You just have to run ./autogen.sh, then ./configure --prefix=/usr/local, make, make install as usual.
alright, I fixed a few bugs. get the first release
here. I also added an example command line app that uses the library.
I'll be adding features to this library as time permits. It currently supports getting the version string and playing the cart in the NES. The next feature I'm going to implement is dump cart.
New version (0.2)
here.
I added support for loading and running plugins on the CopyNES and reading the mirroring byte and the return packets. I have updated the bcn command line tool to use the new features in libcopynes. It now has a "dump" function that takes the name of the plugin rom as a parameter:
./bcn dump nrom.bin
I was able to successfully dump Super Mario Brothers using the nrom.bin plugin. I received the mirroring byte (horizontal mirroring), the 32K PRG packet and the 8K CHR packet. The bcn app isn't able to write out .unf or .nes files yet but I leave that as an exercise for the reader
The next feature I am going to add is support for the various RAM carts, starting with the PowerPak Lite since that's the one I own.
Yeah I was surprised what a pain it was to get the autotools to work. Would you mind posting the source for the bcn sample? I am thinking of building something against libcopynes to allow for making .nes and unif files, and that would be a big help!
The bcn application is on the same
page as libcopynes. Here's a
direct link though.
It'd be cool if you could make your code for creating .nes and .unf files a library too. That way we're building up a set of libraries for all of these common functions.
As I move forward with libcopynes, I'm realizing that most functionality is actually in the client applications. libcopynes is pretty much done at this point, so I'll probably set up a proper project for a fully fleshed out client app that uses a GUI toolkit. I'm thinking wxWidgets or gtk# if I can figure out how to do C# to C interop.
I have to confess that I just set up a windows box with visual studio on it so that I can step through the CopyNES app code. It is a little hard to follow in my head. Once I get a good couple of hours to dissect it, I'll be ready to bang out a fully featured, cross-platform client app for libcopynes.
(This was all much easier than I thought it would be).
I will make functions for making .nes and .unif in library form.
I got the tar for the bcn app, but the source doesn't seem to be included.
oops, sorry. I meant to include that. Try the link again, I updated the tarball to include the source.
On my system I have to run the following commands to compile bcn:
Code:
$ gcc -c bcn.c
$ gcc -o bcn bcn.o -lcopynes -L/usr/local/include/copynes
This assumes that when you installed libcopynes you did the following:
Code:
$ ./configure --prefix=/usr/local
$ make
$ sudo make install
There are functions in the CopyNES source zip file from retrousb.com that write out .nes and .unf files. I added a TODO comment in the bcn.c file on where to call the function that writes out the files.
Good luck and send me patches for any changes you make. I'll make bcn into a proper open source package soon.
This is good stuff. I'm looking forward to seeing how this turns out. I wish I could help you more than just cheering you on
I haven't tried it out yet, but I did want to say that a command-line app for CopyNES is just the kind of thing that's needed.
I just posted a major update to
libcopynes. I switched the library over to using all async I/O on the serial port plus I finally figured out how to properly configure the serial port so that I get the raw, 8-bit data being dumped over the wire by the CopyNES.
I just ran a few tests where I was able to dump a very popular NROM cart into .chr and .prg files using the latest version of
bcn. I then ran those through crade's util for making .nes files from .prg and .chr. I was then able to use the windows CopyNES app to put the .nes file onto my PowerPak Lite RAM car and play it.
I'm convinced that the data I'm getting from the CopyNES is now clean. I'll now be able to move on to supporting more complicated CopyNES plugins.
I'm going to test out the portability of my library soon. I've got an intel Mac and a PPC Mac to test this on. I can also test this on Windows with Cygwin but I don't see the point of that.
If anybody has tested libcopynes and bcn on any platform other than i386 Linux, please let me know. I'm most curious about other "POSIX" platforms like FreeBSD and OpenBSD.
Interesting challenges: Get a GP2X, a Pandora, a Dreamcast, or a GBA to talk to the CopyNES.
I actually have a GP2X with the base that provides USB host support. I don't think that would be very hard to get running since the GP2X runs embedded Linux.
I also happen to have a Dreamcast and a coder's cable and all of the tools necessary to create bootable CD-R's for it. Since there is a Linux port for the DC, theoretically, everything is there except the USB host port. I suppose one could put an FDTI usb host chip on the expansion port of the DC but that would be a lot more work than the "hey, cool" factor of having a DC talk to a CopyNES.
The GP2X would be fun to try, but like everybody else, my time is tight and I'd rather spend it on making a solid NES dev kit together for users of all operating systems.
keep up the good work, this is exactly the sort of thing I've been looking for. Sometimes I feel a bit left out when most people are doing things on Windows and I only have Linux and Macs.
Having a little trouble with the linuxprogrammer.org links, can't seem to grab the tarball or svn checkout, HTTP just times out. But I assume that is only a temporary issue.
If you need free source control, there is also
http://github.com, which is pretty nice once you've learned git because it tracks forked projects and makes it easy to merge in other people's contributions.
Try again. I'm not having any trouble with my servers but if it persists, I'll consider switching to github or sourceforge.
I haven't had any trouble with either the links or the svn.
Wookie wrote:
Try again. I'm not having any trouble with my servers but if it persists, I'll consider switching to github or sourceforge.
works fine for me now. it was just a temporary issue that was happening that day, probably a bad route between you and me.
FYI, the libcopynes project has switch over to mercurial and is now hosted on bitbucket.org here:
http://www.bitbucket.org/wookie/libcopynes
(IMO, mercurial is easier to use that git, and it does pretty much the exact same thing.)