Having trouble with games seeing controller input. Help!

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Having trouble with games seeing controller input. Help!
by on (#216775)
I'm building an emulator in JavaScript and have made significant progress with the cpu and ppu. I've built out the code for gamepad handling and various test roms like bestest work with the input.

However I've tried donkey Kong and balloon fight and the games do not detect input at all. Was wondering if anyone has ran into this before? Note the games aren't frozen and play through the demos fine. It just doesn't see the input.

If anyone is interested the code is at https://github.com/tdondich/vue-2a03-emu/

And the controller component is located at https://github.com/tdondich/vue-2a03-em ... oypads.vue

Thanks for any suggestions.

TD
Re: Having trouble with games seeing controller input. Help!
by on (#216782)
Try logging the bytes read and written to the controller port addresses. Maybe your controller strobe logic is not working properly.
Re: Having trouble with games seeing controller input. Help!
by on (#216785)
Yep, I've done that and like I said, various test roms like nestest and color_test do indeed see the controller and work with it. So just to confirm what I'm looking at is:

An incoming bit 0 value of 1 on $4016, which sets strobe to high (first phase)
An incoming bit 0 value of 0 on $4016, which sets strobe to low (resets the "stream" of data for controller on $4016 and $4017)

then subsequent reads on $4016 or $4017 will send a byte back, with bit 0 indicating the state of the button, and then the next after that, in order of A, B, Select, Start, Up, Down, Left, Right. After 8 reads, any additional reads will return $1 by default with standard NES controllers.

Nothing else to it, right?
Re: Having trouble with games seeing controller input. Help!
by on (#216786)
What are you returning in bit 1? The Famicom sees hardwired controllers on bit 0 and controllers plugged into the DA15 expansion port on bit 1.
Re: Having trouble with games seeing controller input. Help!
by on (#216787)
I'm going off of memory guys, so correct me if I'm wrong please, but aren't both these games reliant upon open bus behaviour, i.e. the cmp/cpx/cpy (not sure which the games use, but probably cmp) is against what might seem like a "non-logical" value? I could be wrong in remembering which games require this (do we have a list on the Wiki?), but it affects several. I also recall this being a struggle point with the very first NES emulators. Wiki reference with quote: https://wiki.nesdev.com/w/index.php/Sta ... 17_read.29

Code:
In the NES and Famicom, the top three (or five) bits are not driven, and so retain the bits of the previous byte on the bus. Usually this is the most significant byte of the address of the controller port—0x40. Certain games (such as Paperboy) rely on this behavior and require that reads from the controller ports return exactly $40 or $41 as appropriate.

I'm not saying this is the cause of problem -- it certainly could be one of many other things -- but it's something that has to be kept in mind.

That said -- and I say this with total respect, no negativity: while asking for help, and providing references to code is helpful and always appreciated, the thing you have to remember is this: most people aren't going to go sift through your entire emulator's code base to understand it just to help you fix a problem. Even linking to just some particular part of your code base (some function/line/file), while it makes sense to you, doesn't make sense to us without significant investment. For example, AFAIK, not many people here are familiar with Javascript (and I imagine even less so with Vue.js) -- we're more familiar with slightly less abstracted languages like 6502 assembly, C, C++, Python, Perl, etc.. We can explain to you how the NES works, but we often can't (without investing all that time) tell you exactly what's wrong with your emulator's emulation. On occasion someone will do something like post a screenshot of a problem they're having with, say, emulating the attribute table or PPU stuff, and provide a screenshot of results along with a core piece of code logic (in a PL we're familiar with), and someone will go "that looks a lot like you might have X/Y/Z bits set wrong, or your calculation for X/Y/Z is wrong", and the author goes "OMG you're right! That fixed it!" and the problem is solved. But this is generally quite rare. So please keep that in mind.
Re: Having trouble with games seeing controller input. Help!
by on (#216788)
Use a debugger is all I can say. Simply by setting a breakpoint in get() (and maybe set()) you should be able to find out if the values propagate properly to the game code. If that doesn't solve the problem, then I'd start stepping through the 6502 emulation code (again, in a debugger) while looking at the disassembly of the Donkey Kong controller reading code. It's probably a loop gathering the 8 controller bits in the accumulator. You can fairly easily verify what value it ends up with.
Re: Having trouble with games seeing controller input. Help!
by on (#216789)
tdondich wrote:
An incoming bit 0 value of 1 on $4016, which sets strobe to high (first phase)
An incoming bit 0 value of 0 on $4016, which sets strobe to low (resets the "stream" of data for controller on $4016 and $4017)
In addition to what koitsu said, this is slightly off.

While strobe is high, the "stream" is continuously reset. Reads from $4016 while strobe is high always return the first bit (usually the "A" button)
Re: Having trouble with games seeing controller input. Help!
by on (#216790)
koitsu wrote:
I'm going off of memory guys, so correct me if I'm wrong please, but aren't both these games reliant upon open bus behaviour, i.e. the cmp/cpx/cpy (not sure which the games use, but probably cmp) is against what might seem like a "non-logical" value? I could be wrong in remembering which games require this (do we have a list on the Wiki?), but it affects several.

Donkey Kong's controller read does not rely on open bus behaviour. It explicitly does 8 reads, and it ORs the two bottom bits together. There's no CMP involved. (It looks like a very normal and robust method to me.)
Attachment:
donkey_kong_controller_read.png
donkey_kong_controller_read.png [ 3.76 KiB | Viewed 3718 times ]


Paperboy is the only example I see listed on the wiki of the kind of thing you're referring to. (Tricky-to-emulate games, and redundantly at Open bus behaviour, Standard controller) Balloon Fight is on the "tricky" list but not for anything to do with the controller.
Re: Having trouble with games seeing controller input. Help!
by on (#216792)
First off, thank you to everyone who responded. I'm pretty new to the forums so I appreciate the patience if I ask something that was referenced somewhere else. Yep, the emulator is in javascript, yep I'm insane for doing such a task. That primary reason I wanted to do it was to utilize vue.js so I could build debugging tools quickly. Came along pretty well and I'm glad to be at this point.

@tepples: I don't return anything in bit 1 when reading. I either return 0x01 (button pressed), or 0x00 (not pressed). No support for additional controller types are made at this time.

@koitsu: I don't handle open bus behavior at this time. Looks like rainwarrior clarified and grabbed the input loop I was going to fetch out of the code and it looks like it's a clean grab with no evaluation of open bus data.

@lidnariq: Yeah, I actually just read that this morning. My code doesn't do that necessarily (in that situation, it'd return 0x01). So I'll make sure that when strobe is set high, it just constantly returns the state of the A button.

@thefox: Yep, I'll have to set a cpu breakpoint in the emu and run through each command. Thankfully, @rainwarrior shows the address where input loop starts.

I'll post findings of the debugging log later today after work.

Thanks again everyone!

TD
Re: Having trouble with games seeing controller input. Help!
by on (#216793)
@rainwarrior -- thanks for correcting me! I just remember that in early NES emulator days (~1996/1997), there were several games that people had to do strange quirks to get controller reads working right. I vaguely recall values $80, $01, or $40 were somehow involved. I don't remember context, sadly.
Re: Having trouble with games seeing controller input. Help!
by on (#216794)
tdondich wrote:
Thankfully, @rainwarrior shows the address where input loop starts.

It's really very quick to find if you know how to look for it. i.e. open a debugging emulator (e.g. Mesen/FCEUX/Nintendulator) and put a breakpoint on reads from $4016, it'll pop up right away.

koitsu wrote:
@rainwarrior -- thanks for correcting me! I just remember that in early NES emulator days (~1996/1997), there were several games that people had to do strange quirks to get controller reads working right. I vaguely recall values $80, $01, or $40 were somehow involved. I don't remember context, sadly.

The values read through $4016 on a NES are normally $40 or $41. The reason why is described on the wiki. (There are ways to get other values too, though. This should not be hard-coded as $40 or $41, it should implement the actual open bus behaviour, which that wiki page describes.)
Re: Having trouble with games seeing controller input. Help!
by on (#216795)
I think there's only one thing that'll really break if you always return $40 for unpressed or $41 for pressed, and it's the "region check" functionality of allpads that can tell Famicom from NES-001 from NES-101.
Re: Having trouble with games seeing controller input. Help!
by on (#216796)
@Rainwarrior , is there any documnentation on what addresses would have open bus behavior on the cpu data bus?

And let me clarify, the value that will be returned on $4016 should be based on how it was addressed. Since most control pad read loops use absolute addressing, that's why the bits 7 - 4 will be set with 010, since it's the bits in the high byte of val 0x4016. Correct? The only way it'd be different is if it was addressed differently.

TD
Re: Having trouble with games seeing controller input. Help!
by on (#216803)
So I fixed it. Apparently after debugging, I did see the routine that @rainwarrior shared indeed worked fine. The problem was the following routine at $F533 which determines if there was any input. It does an ASL $00. And well, my ASL routine would be passed in the location, which would be $00 and the ASL wouldn't recognize that as a valid address (it equated to falsy) and instead thought it should do the ASL on the accumulator instead of the memory location. Once that was fixed, I was playing my emulator!

Thanks everyone for the assistance.
Re: Having trouble with games seeing controller input. Help!
by on (#216812)
tdondich wrote:
So I fixed it. Apparently after debugging, I did see the routine that @rainwarrior shared indeed worked fine. The problem was the following routine at $F533 which determines if there was any input. It does an ASL $00. And well, my ASL routine would be passed in the location, which would be $00 and the ASL wouldn't recognize that as a valid address (it equated to falsy) and instead thought it should do the ASL on the accumulator instead of the memory location. Once that was fixed, I was playing my emulator!

Thanks everyone for the assistance.


Nice. Glad you got it working.

Just out of curiosity, why didn't the instruction set test ROMs detect an issue with ASL ?
Re: Having trouble with games seeing controller input. Help!
by on (#216817)
I am only speculating because I am at work at the moment but the nestest probably ran the zero page addressing mode of ASL on a zero page address other than $00. My opcode handler would work just fine in that situation.
Re: Having trouble with games seeing controller input. Help!
by on (#216820)
tdondich wrote:
@Rainwarrior , is there any documnentation on what addresses would have open bus behavior on the cpu data bus?

And let me clarify, the value that will be returned on $4016 should be based on how it was addressed. Since most control pad read loops use absolute addressing, that's why the bits 7 - 4 will be set with 010, since it's the bits in the high byte of val 0x4016. Correct? The only way it'd be different is if it was addressed differently.

Hmm, I think the open bus article could use some additional info about what regions may be open bus.

Yes, you can get a different result by using indexed addressing from a lower address, but I think a PowerPak or Everdrive (or other cartridge) might have the potential to alter the open bus behaviour in different regions as well. I don't know the specifics of this. I think tepples tested it a while back.

zeroone wrote:
Just out of curiosity, why didn't the instruction set test ROMs detect an issue with ASL ?

The test ROMs probably don't test every instruction on every possible address. ;)
Re: Having trouble with games seeing controller input. Help!
by on (#216822)
Results from Riding the open bus are that PowerPak pull-ups modify the open bus behavior, but EverDrive does not.

But if you're still getting games to run, don't worry too much. That test ROM and derivatives thereof are probably the only thing that relies on any difference between open bus in bits 7-5 and just driving them to 010 (the upper bits of $40/$41). And even then, the only difference is probably that the NES controller graphic will or won't be turned into a dogbone or an RF Famicom controller I or II.
Re: Having trouble with games seeing controller input. Help!
by on (#216825)
tepples wrote:
Results from Riding the open bus are that PowerPak pull-ups modify the open bus behavior, but EverDrive does not.

Was that only testing the overlap with registers?

I seem to recall that Everdrive's $6000-7FFF area is subject to a different behaviour (when RAM is not mapped) than the NES open bus?