It is currently Sun Jul 22, 2018 12:11 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Wed Apr 11, 2018 9:19 pm 
Offline

Joined: Fri Mar 23, 2018 4:21 pm
Posts: 12
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


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 6:52 am 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 777
Location: New York, NY
Try logging the bytes read and written to the controller port addresses. Maybe your controller strobe logic is not working properly.


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 9:27 am 
Offline

Joined: Fri Mar 23, 2018 4:21 pm
Posts: 12
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?


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 9:49 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20282
Location: NE Indiana, USA (NTSC)
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.


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 9:58 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3435
Location: Mountain View, CA
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.


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 10:26 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 3090
Location: Tampere, Finland
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.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 10:41 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7322
Location: Seattle
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)


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 10:49 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6425
Location: Canada
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 1168 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.


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 11:38 am 
Offline

Joined: Fri Mar 23, 2018 4:21 pm
Posts: 12
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


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 11:49 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3435
Location: Mountain View, CA
@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.


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 1:20 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6425
Location: Canada
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.)


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 2:18 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20282
Location: NE Indiana, USA (NTSC)
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.


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 2:31 pm 
Offline

Joined: Fri Mar 23, 2018 4:21 pm
Posts: 12
@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


Top
 Profile  
 
PostPosted: Thu Apr 12, 2018 10:15 pm 
Offline

Joined: Fri Mar 23, 2018 4:21 pm
Posts: 12
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.


Top
 Profile  
 
PostPosted: Fri Apr 13, 2018 6:49 am 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 777
Location: New York, NY
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 ?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group