Im wondering about a couple of things with the PC to NES Transfer cable modification.
http://wwwk.heltech.edu.hel.fi/koti/sepi/nes/nes.htm#4
I can not make any sense of the schematics, they read like hyroglyphics.
After reading a few other topics about this on other forums, im begining to think that you need a dev/custom cartridge for the transfer cable to work. Is this the case?
It would be nice to see a picture or two of a completed cable.
Thanks.
You should use EDIT to view the schematic, don't use notepad. It says so in the beginning of the document
As for the irq.prg, it's just a simple test program, i used it to test if the host PC program is cabable to trap all gamepad pollings. It's not required to build the transfer cable.
PC to NES transfer cable was originally designed to be bi-directional, due the complexity of the NES to PC comm. this feature was removed. If you are looking for a way to communicate from NES to PC you should see the NES to UART schematics by Memblers.
Nesdev is currently hosting the updates of lptnes.exe, due the antivirus restrictions i can't upload .exe | .zip | .rar files to my homesite.
Memblers told me that he is going upload stuff to nesdev pretty soon, then the latest version of lptnes.exe (1.10) should be available.
- Sepi
I had checked out the schematics with edit, still a little complicated for me. I wasn't really interested in NES to PC communication, just the ability to control the NES games with a PC peripheral.
On another forum I had come accross a post where some individual had found one of these cables at a flea market for $1, but sadly it did not work. They had explained to me that it was just a straight through cable, no breakout box or IC's in there!?! Now I know this can't be right... can it?
From what I understand about the schematics, there are a few IC's, some resistors and a few other things in there.
Thanks.
http://nesdev.com/lptnes.zip
I uploaded the file, haven't updated the site index yet though.
Quote:
On another forum I had come accross a post where some individual had found one of these cables at a flea market for $1, but sadly it did not work.
It might've been a Miracle piano adapter, I found one of those too and wondered what it was for a while. I think there is a circuit inside it, looking in one of the tiny holes on the DB25 shell I can see some green (probably a PCB).
The instructions and schematic in that version are a bit easier to understand. The only concept im not grasping is the whole /IRQ [LPT] thing. Were does that connection come from? Its not listed on the LPT pinout.
Wondering if these wire colors are right:
Brown = GND
Yellow = CLK
Orange = P/L
Red = Q1
White = +5v
Thanks.
Doh! it's supposed to be /ACK (pin.9) instead of /IRQ
I'm not sure about those colors, you should probably check them with multimeter.
- Sepi
Well, now it all makes sense!
Im pretty sure the colors are correct, I checked over a few other pinouts and the colors match the functions.
I looked up the 4021 datasheet and compiled this out of it:
Updating Diagram
Does this wiring look correct?
Edit: Well, I wired up my cable just like I laid it out in my wiring diagram. When I load up lptnes.exe on my PC and select R to record an NES movie, it asks me for a file name and then to hold reset. I do that and lptnes.exe responds when I release reset saying "Released". This is as far as I can get it to go. The NES does not respond to any keyboard keys pressed, and the log files generated by lptnes.exe are empty.
Any ideas what maybe wrong with my wiring?
Edit: When I change the properties of my LPT port from bi-directional (which gives me 0k .NCL files) to ECC or any other setting, I get information being logged into the .NCL file. One .NCL file I logged was 23k in size. Still no response from the NES in any LPT mode.
Edit: Well, I just spent the last hour or so re-wiring my cable and this time it worked. I am able to control the NES with the keyboard, am able to record NES movies and am able to playback NES movies (they de-sync but thats ok). Now im going to wire up a brand new cable and see if I can reproduce the same results.
Thanks.
That's great if it works!
Do you have parasite-power and pull-up resistor connected to /ACK?
for me the internal pull-up was insufficient. Does the reset trapping say ok?
By the way, which deck you have PAL or NTSC?
I have yet to wire in the parasite power and the pull up resistor, I am planning on doing this when I get a few diodes.
The purpose of the parasite power and pull up resistor is for more acurate reset trapping, is it not?
Yes, the reset trapping does say ok. Its kind of neat to release the reset button on the NES and have the PC respond!
Im using a NTSC console for this modification.
Now im wondering if it would be possible to get the lptnes.exe source, I would like to be able to re-map my keyboard buttons, and a few other tweaks.
Edit: Sepi, would you mind posting one of your .NCL files?
Thanks.
Yup, parasite power keeps the /ACK line in high state even if you press RESET or Power-off, when you release reset button, the pseudo-random numbers get (hopefully) exactly same seed number. However, there is numerous games that still fail sync, even if you trap the reset.
Actually, i got the idea for the reset trapping from Memblers! They were talking about this at cherryroms hardware forum.
I'm planning to update the lptnes.exe in future, custom gamekeys is one the features that i'm going to implement. If you have some ideas, it would be great to hear about them!
I'm not releasing the lptnes.exe source, not just yet. I'm still considering if i'll release it or not.
Yeah, i'll post few .ncl files to my homepage shortly. They have been recorded with PAL deck/games, there's a change they don't work at all.
DrNES, i don't have a NTSC deck available, and i need someone with NTSC deck to test if the PAL/NTSC detecting works correctly, would you like to be beta-tester?
I was also thinking of making a movie playback device for my NES and plan on synchronizing by monitoring the joypad clear ($4016.0). Each high-to-low transition would register as a "read current joypad state" event, and these would be the only events that count for anything. This way the timing doesn't matter when playing back, just that the game reads the joypad the same number of times. Maybe this is what you're already doing; if so, what is causing the synchronization problems? If it's random power-on values, on my NES turning the power off for several seconds yields the same initial values in memory.
Im not sure why movies de-sync so often, I remember reading somthing about random resets within the game itself cause this effect.
Perhaps if the software logged key presses on a strict timeline basis, then it could be played back based on the timing of the key presses. Or if the software could detect these "resets" within the game and adjust the log file to suit more accurate playback.
Thanks.
Yes, that the lptnes does. As the NES transmits a P/S, /ACK line is pulled low thus generating a interrupt.
For reasons unknown, Bregalad pointed out that some games poll (such as smb3) gamepads twice.
In the current lptnes version, there's all sort if crap in the interrupt vector. This may cause desyncing, if there is more than one polling in the NMI. Next revision will have "clean" interrupt vector, this might fix some games (or not).
I belive that the random number generators are the biggest problem; if the random number generator is located off NMI, and|or the gamepad is polled faster than 1/50|60. Maybe i should perform some benchmarking with issue, how fast P/S transients lptnes is cabable to intercept?
Tetris is a excellent example; i have never succeeded replaying a movie correctly.
-sepi
Which version of Tetris have you tested with?
I tested Tengen Tetris with my cable, it seemed to work rather well. I wasn't recording it like I would play Tetris myself, I was only using 1 or 2 buttons at a time and placing the blocks very slowly.
Im sure if I kicked it up to full playing speed that it would de-sync very quickly.
Thanks.
Tetris != Tetяis. I'd guess that sepi was talking about Nintendo Tetris, the only NES tetramino game to use "Dance of the Sugarplum Fairy" as the background music.
And does it desync with
Tetramino (for DreamEmulation) (PD)?
I've just built the NES movie player today and successfully played back a few minutes of me playing Rygar, trying to do things that would depend on precise timing, with several areas of slowdown. I recorded the movie on my emulator and played it back on my NES with a standard Rygar cartridge, so it was a good test of accuracy on both ends. My emulator records new joypad data only when the strobe has gone high then low for that frame, which is essential for playing it back correctly. I also successfully ran a second test where I modified my emulator to add an extra 5000 clocks to each video frame, and it still played back exactly the same on the NES.
I implemented it as I described, where my code has the next controller data already continuously applied to the 8 data inputs of the 4021 shift register so the next time the NES raises the strobe, it gets the new data without the replay processor having to be very fast. My code waits for the strobe to go high then low, then sets up the next controller data. I added a latch to the strobe monitor on my replay processor so it wouldn't miss the strobe quickly going to high then low (I'm using a Tandy 102 to replay, which has a 2 MHz 8085 processor).
I've also consistently replayed a movie of Castlevania, where the timing relative to power on affects what random items you get. It didn't match that in my emulator, probably due to some inaccuracy in it.
I was able to use the strobe as a power-on indicator to the replay processor, since at power-up it goes high. I had it wait until the strobe went high, then until it went low, then began normal playback.
This will be a great tool for testing emulator accuracy, and proving that those tool-assisted recordings are really possible on an actual NES, and not just hacks.
I must have somthing wired incorrectly within my cable/circuit. Game control and recording are fine, playback on the other hand is horrendous.
Im quite suprised I even got this far with the project.
I added the ability to record movies from the PC keyboard while playing on the actual NES, and have successfully recorded and played back 3-5 minute movies of Rygar, Battletoads, Wizards & Warriors, Mega Man, Blaster Master, Castlevania, and Metroid. While playing each I did as much as I could to cause slowdown and tricks that would require exact sync when replaying.
All the movies played exactly the same each time, including random items and enemies. The only anomaly was that the message before the level on Battletoads wasn't always the same, so apparently they're initializing their random number generator in a way that takes advantage of some inconsistency, perhaps the values of PPU memory at power-up. I couldn't get Super Mario Bros. 3 to record, probably due to it checking the joypads twice in a row and too quickly for my replay processor to keep up.
To reiterate, the replay processor isn't doing *any* timing on its own; it's simply getting the next joypad data when the strobe line is clocked. The main reason I'm posting these results here is to confirm that the lpt2nes hardware should be able to record movies without desync (at least the the games mentioned). The software, on the other hand, I don't know about.
One reason I'm not using my PC directly is because I doubt I could get the timing right with it without resorting to some tedious driver-level programming. With a small 8-bit CPU, it's easy because I have complete control over its operation. Heh, I guess if I had a second NES, I could have *it* do the recording and playback.
I'd like to help get this project working better for everyone, since it provides a good standard for NES movies and testing emulators (and is just plain cool).
UPDATE: I tried and tried with Super Mario Bros. 3 but couldn't even get Mario to move properly on the map when playing back! I did verify that my replay processor was fast enough to handle the four strobes it does every frame. I want to solve this because most later Nintendo titles strobe the joypad multiple times each frame.
I did successfully record and play a Bionic Commando movie, and got a Castlevania III movie to play most of the way through until it lost sync due to the random number generator (enemy not appearing where it did when recording). I'm not sure why that happened.
Would you be willing to let others test out the code you have written?
If the playback issues are limited to the lptnes software and not the hardware, perhaps people interested in the project could contribute to a new application?
The code is all for a custom setup; my PC is an old PowerMac and I'm using a Tandy 102 portable computer (8085 CPU), wired to my PC via RS-232, as the interface with the NES. The algorithm and hardware are so simple that it would make more sense to just document that.
I've got a 4021 shift register connected to the NES the same way as for a normal joypad. In place of the joypad buttons is an 8-bit latch. I also have the strobe output from the NES connected to an input on the Tandy.
My record/play code does the following:
Code:
byte movie [];
int movie_size;
// Go through each byte of controller data in the movie
for ( int i = 0; i < movie_size; i++ )
{
// To record, uncomment this line
//movie [i] = read_pc_keyboard();
write_latch( movie [i] );
// Wait for strobe to go high
while ( read_strobe() == 0 ) { }
// Wait for strobe to go low
while ( read_strobe() == 1 ) { }
}
The first time through the loop it effectively waits until the NES is powered up, where the strobe line initially goes high, then low at some point. From there on, it waits until the strobe line goes from high to low before writing to the latch, since the new data won't be needed until the
next time the strobe line goes high then low, which will usually be 1/60 second later. The alternative, to wait for the strobe to go high then quickly put new data on the latch before the NES sets the strobe low again, places extreme timing requirements on the replay code:
Code:
// Wait for strobe to go high
while ( read_strobe() == 0 ) { }
write_latch( movie [i] );
// Wait for strobe to go low
while ( read_strobe() == 1 ) { }
Since the Tandy is fairly slow (the 6502 kicks the 8085's ass), it might not notice the strobe go high then low, so I also have a clocked flip-flop connected to the strobe from the NES. It's wired to become set when the strobe line goes from high to low, and cleared when the Tandy asserts its clear line. This takes pressure off the Tandy as far as having to be really fast at responding. Effectively the 8-bit output latch and this flip-flop form a buffer that the Tandy can refill at its leisure. The code is basically unchanged:
Code:
write_latch( movie [i] );
clear_flip_flop();
// Wait for high-to-low transition of strobe
while ( read_flip_flop() == 0 ) { }
Looking at the lpt2nes schematic (after figuring out how to decode the non-ASCII text) it all depends on how the software monitors the line labeled /IRQ, which is fed an inverted version of the strobe. Since the algorithm above is so simple, my guess is that the problems are due to the difficulty in getting precise timing on a PC, or possibly differences in parallel port implementations.
I think it would be possible to make a version of this that made the NES look just like a normal parallel printer, so you could use any software to "print" the stream of bytes to it and let the normal operating system buffering send the data at the rate the NES is reading it. This would need a 74374-style latch and maybe a flip-flop. This would allow recording and playback.
You could use this to send binary data to the NES, given the proper code running on the NES. It'd be quite fast, probably around 8KB/sec. Still wouldn't be as nice as the super-simple MAX-232 serial interface which allows you to send data back to the PC, but at least it wouldn't use as much NES CPU time and would have built-in flow control.
EDIT: I just thought more about the lpt2nes setup and realized that maybe it's maybe already up to look like a parallel device. The PC outputs the byte and waits for /ACK to go low, then outputs the next byte. /ACK is tied to the inverted strobe, so it's usually high. It seems that it'd need a flip-flop or something, otherwise it would assert the /ACK line when the strobe went high, and then the PC might output new data at any time after that, which might be before the strobe went low (which is the real event you want to watch for). Since the /ACK line (I think) is level-sensitive, rather than edge-sensitive, you need an edge-sensitive flip-flop. It could be set on a high-to-low transition of the strobe, and cleared via the joypad clock.
Code:
; Usual joypad read code on NES
lda #1
sta $4016 ; strobe -> high
; /ACK line is currently asserted here
lda #0
sta $4016 ; strobe -> low
lda $4016 ; clock: low->high->low
; /ACK line would be asserted here
I think /ACK line is edge triggered, but i'm not 100% sure about this.
As far as i know, lptnes is cabable to trap a standard polling procedure, i tested this with a special test program.
I have tested the latest version of lptnes with castlevania, and i always got the same random pickups, sometimes the scores were not equal (+/- 100 pts) Super Mario Bros 3 doesn't work for me either.
DrNES, try to record movies with Super Mario Bros, this game has never failed in my tests! also, The Smurfs seems to be 100% accurate for me. Both versions has replayed these games correctly.
- Sepi
Im going to work on my hardware design just a little more, then I will get into some serious SMB/Duck Hunt testing.
My main goal of this project was to be able to play Tetris with a keyboard, ive accomplished that much. Now getting movies to record an playback correctly is my new goal.
Thanks.
I found a nice
summary of the PC parallel port and it confirms that /ACK is triggered on a low-to-high transition. I've worked more on making my interface act like a standard parallel device, but apparently the Tandy doesn't hold the data until I indicate not busy (it uses the internal 8-bit latch for other things too, like scanning the keyboard). I've tried several arrangements and have come full-circle and think that lpt2nes should probably work as-is, as long as the PC holds the data until the /ACK line goes high.
Does the driver for lpt2nes simply repeatedly call the "write byte to parallel port" function, or something else? You mentioned 50/60 Hz timing, but that seems unnecessary to even bother with.
i have only tested this with nintendo tetris, not tengen version. I checked the P/S line with oscillosope, this game polls gamepad twice in NMI (generating random numbers?)
I haven't tested the recording with the tetramino yet, i noticed that lptnes desyncs quite awfully with battletoads and wizards & warriors
and also metroid desyncs. I think my current test setup sucks quite a lot, currently i don't have TV (i just moved recently) so i'm using my PCs videocard to repeat the TV image.
lptnes reads keyboard and writes it to dataport after receiving interrupt from /ACK, Off-NMI it stays in a while loop.
Maybe my playback/recording buffer is the "bottleneck"? i can't figure out any reasons why the battletoads should not work. As far as i know, it doesn't use any obscure polling routines.
I've done more tests with Metroid (recording on my emulator and playing on the NES) and I haven't encountered any issues yet. I found that Battletoads is somehow generating different random numbers each time, so if I let the enemies do much moving around it won't replay.
Quote:
I think my current test setup sucks quite a lot, currently i don't have TV (i just moved recently) so i'm using my PCs videocard to repeat the TV image.
I love being able to use the video-in on my computer and not have to keep a boxy TV on the desk. Sure the video capture doesn't compare to a real TV, but it's great for development.
Quote:
lptnes reads keyboard and writes it to dataport after receiving interrupt from /ACK, Off-NMI it stays in a while loop.
If the PC-side software is trying to figure out if the NES is in NMI or not, that will likely add problems. The PC-side software should wait for /ACK, output new data, then loop back to waiting for /ACK again. If interrupt latency is low enough, you should be able to output new data in the interrupt handler and get rid of a busy-wait loop. For games which poll only once per frame, this allows almost 1/60 second interrupt latency without problems, since the data you output is for the next joypad read. If it polls twice per frame in succession, you'll need quite low latency.
I modified my emulator to print the times between polls (when the strobe goes from high to low) and compiled results for many common games:
These poll at most once per frame: Battletoads, Castlevania, RC Pro-Am, Super Mario Bros., Deadly Towers, Kid Icarus, Mega Man 1-6, Mighty Bomb Jack, Rygar, Section-Z, Ghosts'n Goblins, Legacy of the Wizard, Rad Racer, River City Ransom, Solomon's Key, Solstice, The Battle of Olympus, Wizards & Warriors, Wizards & Warriors 1-3, Duck Tales, Duck Tales 2, Karnov
These consistently poll more than once per frame (delays between polls in parenthesis, in CPU clocks): Castlevania 3 (387), Fester's Quest (395), Rod Land (162 163 156), Super Mario Bros. 2 (372), Super Mario Bros. 3 (215 276 215), Zelda (29 232 273 232), Zelda 2 (247), Batman (380), Blaster Master (282), Castlevania II (387), Contra (381), The Goonies II (379), Metroid (302), Rambo (polls almost 100 times per frame, hahaha), Snake's Revenge (394), Super C (387), The Guardian Legend (377), Kirby's Adventure (148 191 148), Magic of Scheherazade (200), Maniac Mansion (262), Ninja Gaiden 1-3 (223), RC Pro-Am 2 (627), Nintendo Tetris (398), TMNT 1 (387)
After re-wiring a new cable up (this time got it all to fit in a DB-25 hood) and switching to another PC, ive had perfect playback results with a few games...
SMB
SMB\DuckHunt
MegaMan 2
GunSmoke
Ive still got another 80+ games in my collection to test, I will post a summary of what works and what doesn't work for me when testing is done.
Thanks.
lptnes doesn't read anything from statusport, it simply stays in the while loop until a variable is !=0, and then the ISR will increment this variable. I assume that P/S transition means that NES executing NMI, and the P/S line will remain at 0V for a ~20ms, i use this "idle" time for rec./play routines etc. i suppose that for metroid and tetris is way too slow?
Quote:
I assume that P/S transition means that NES executing NMI, and the P/S line will remain at 0V for a ~20ms, i use this "idle" time for rec./play routines etc. i suppose that for metroid and tetris is way too slow?
With 100 CPU clocks taking about 0.056 msec, you'll be way too slow on games that poll multiple times. Metroid reads once, then again about 0.168 msec later. Even for games that read only once per frame, that would be every 16.7 msec, more often than every 20 msec.
Some of these are polling the second joypad, so the second strobe could be ignored. You could add a clocked flip-flop in there and only signal when the strobe line is pulsed and the controller 1's clock line is pulsed. I was able to arrange this with a single 4013 dual flip-flop in one iteration of development. I just re-checked all the games I listed above that strobe the joypads more than once. Of them, only following read joypad 1 once (they apparently are scanning joypad 2 the second time): Metroid, Maniac Mansion, Kid Icarus. I guess this modification would only help those games that read joypad 2 separately (Metroid and Kid Icarus allow you to pause then press up and A on joypad 2 to get the password immediately).
Is there any way to queue up data for the system to output immediately each time the /ACK line goes high? That way you could queue up a few bytes and let it respond quickly and efficiently, while your code simply polls the buffer and refills it when it gets low. Your code should easily be able to do its housekeeping in under 1 msec, unless you're running this on a 50 MHz machine. :)
I had that 4013 in the previous version of the transfer cable, but i removed it because i wanted to add a SNES support to this revision. I think this double polling issue can be resolved with counter too, so sacrificing the /strobe line isn't really necassary.
Maybe should connect the /ACK to the nes CLK? this might resolve the double polling issue quite easily.
The developement version of lptnes works basicly just like you described, the version 1.10 is slightly slower. Maybe i should output a low to high transition at /strobe line for a benchmarking purposes?