It is currently Sat Nov 18, 2017 7:15 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: APU Addresses in FCEUX?
PostPosted: Mon Feb 08, 2016 3:20 pm 
Offline
Formerly AlienX
User avatar

Joined: Fri Apr 18, 2014 7:41 am
Posts: 133
Location: Bulgaria
Another FCEUX question (cause those totally get answered). I tried accessing the some of the APU addresses in FCEUX ($4002, for instance) only to discover, that there's nothing there. I used some of the tools, including Memory Watch and the Hex editor, but the address only shows an unchanging value of FF, when it's supposed to be constantly changing, when the first square wave channel is playing different notes. I suppose the actual addresses have been slightly shifted, but I look all around and I can't find anything. The only addresses, that seem to change with the music in the game are $00F7, $00F8 and $00F9, but even the changes there don't always make sense and besides, the NES APU uses much more bytes. So, where are those bytes?
I really hope someone can answer this question.

Thanks.

_________________
Greetings! I'm That Bio Mechanical Dude and I like creating various stuff like movies, games and of course chiptunes!
You can check out my YouTube Channel.
You can also follow me on Twitter.


Top
 Profile  
 
PostPosted: Mon Feb 08, 2016 3:30 pm 
Offline
User avatar

Joined: Mon Oct 01, 2012 3:47 pm
Posts: 153
Location: freemland (NTSC-U)
from the wiki:
Quote:
(NES APU registers) are write-only except $4015 which is read/write.


This would explain why reading from the APU registers doesn't give you any values. Each game has its own way of writing sound data to the PPU, so you'd have to find that first (by checking the code for writes to those registers).


Top
 Profile  
 
PostPosted: Mon Feb 08, 2016 3:37 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1823
Location: DIGDUG
FCEUX (and Nintendulator) shows the CPU addresses 4000-401f as FF, open bus.

It's a shame they can't just show you the APU registers. How hard would that be?

You could set breakpoints in the debugger for writes to 4000-401f.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Mon Feb 08, 2016 4:08 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6440
Location: UK (temporarily)
NO$NES will let you observe the APU registers.

The reason that they show the region as open bus is because it is open bus. Putting the register values there will just confuse when the debugger reports something different than what the CPU sees.


Top
 Profile  
 
PostPosted: Mon Feb 08, 2016 4:10 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19222
Location: NE Indiana, USA (NTSC)
Would a "☑ Show last value written to write-only registers" checkbox confuse?


Top
 Profile  
 
PostPosted: Mon Feb 08, 2016 8:57 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5822
Location: Canada
The memory view in the debugger should show the state of memory, not internal registers. If it's not something you can read from, it should display the open bus value.

It would be better just to have a separate internal registers inspector, including APU state, PPU state (mostly viewable in the debugger already). Ideally it would also show mapper register states, but obviously that'd be a lot of extra work to add a state poll and annotations interface to every implemented mapper. Maybe the easiest thing for now would just be an APU inspector.

If you can convert whatever it is you're doing to an NSF, NSFPlay has a partial APU register display called "keyboard view", but it doesn't tell you everything (e.g. length counter and sweep state is hidden).


Top
 Profile  
 
PostPosted: Mon Feb 08, 2016 10:09 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19222
Location: NE Indiana, USA (NTSC)
rainwarrior wrote:
It would be better just to have a separate internal registers inspector, including APU state, PPU state (mostly viewable in the debugger already). Ideally it would also show mapper register states, but obviously that'd be a lot of extra work to add a state poll and annotations interface to every implemented mapper.

Unless you're cpow and your number is 1-800-NESICIDE.


Top
 Profile  
 
PostPosted: Mon Feb 08, 2016 10:14 pm 
Offline

Joined: Sun Mar 03, 2013 1:52 am
Posts: 94
Location: Texas, USA
Unfortunately, the way the sound registers work on the NES, the internal register values can't be read back by reading the register addresses. FCEUX's memory viewers show the exact same thing the NES program would see if it read those address.

    If the NES program wants to be able to check the current value of a register, then every time it writes to a register, it has to both write to the (non-readable) register and write a copy to another readable RAM address, so it can read the copy back from the readable address later. It sounds like the program you're currently looking at is storing some sort of music values at addresses $00F7 to $00F9, but they might not be an exact copy of any register values. (For example, they might be "note numbers" that get converted to a period register values via a lookup table.)

If you are using FCEUX's lua scripting, you can gather some information about the current sound register values by using sound.get(). In the help file, go to the Lua Functions List and search for sound.get() to see the overview of what's available. Then see the examples SoundDisplay.lua and SoundDisplay2.lua included with FCEUX or see my example script Scrolling Pitch Display.

Otherwise, I haven't found an easy way to peek at the current sound register values in FCEUX.

    Here's a complicated idea I've thought of, but haven't tried: Use FCEUX's lua memory.registerwrite to capture any attempts to write to the sound registers. When a write to a sound register is captured, examine the currently executing instruction using memory.readbyte(memory.getregister("pc")), figure out what CPU register is the value being written based on the instruction, then get that CPU register's value (using memory.getregister) and display it on the screen or store it in a lua variable or array or something.


Top
 Profile  
 
PostPosted: Tue Feb 09, 2016 6:11 am 
Offline
Formerly AlienX
User avatar

Joined: Fri Apr 18, 2014 7:41 am
Posts: 133
Location: Bulgaria
Bavi_H wrote:
If you are using FCEUX's lua scripting, you can gather some information about the current sound register values by using sound.get(). In the help file, go to the Lua Functions List and search for sound.get() to see the overview of what's available. Then see the examples SoundDisplay.lua and SoundDisplay2.lua included with FCEUX or see my example script Scrolling Pitch Display.

Reading this is kind of ironic, because reading the actual addresses is the alternative to sound.get() I'm trying to make. It seems that FCEUX updates the APU information, provided by the function, once the frame has finished playing. I'm writing a Lua script, that needs to be synced with the changes in the sound channels, and using sound.get() creates a one frame delay. This is why I want to be able to get information directly from the APU's RAM addresses, so that my script can update along with them.

Bavi_H wrote:
Here's a complicated idea I've thought of, but haven't tried: Use FCEUX's lua memory.registerwrite to capture any attempts to write to the sound registers. When a write to a sound register is captured, examine the currently executing instruction using memory.readbyte(memory.getregister("pc")), figure out what CPU register is the value being written based on the instruction, then get that CPU register's value (using memory.getregister) and display it on the screen or store it in a lua variable or array or something.

I might try that. There doesn't seem to be any other solution at this point.

_________________
Greetings! I'm That Bio Mechanical Dude and I like creating various stuff like movies, games and of course chiptunes!
You can check out my YouTube Channel.
You can also follow me on Twitter.


Top
 Profile  
 
PostPosted: Tue Feb 09, 2016 6:14 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2981
Location: Tampere, Finland
It's very unfortunate that the value being written doesn't get passed to registerwrite().

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


Top
 Profile  
 
PostPosted: Tue Feb 09, 2016 6:27 am 
Offline
Formerly AlienX
User avatar

Joined: Fri Apr 18, 2014 7:41 am
Posts: 133
Location: Bulgaria
thefox wrote:
It's very unfortunate that the value being written doesn't get passed to registerwrite().

So does that mean, there's absolutely no way to read the state of the APU on time?

_________________
Greetings! I'm That Bio Mechanical Dude and I like creating various stuff like movies, games and of course chiptunes!
You can check out my YouTube Channel.
You can also follow me on Twitter.


Top
 Profile  
 
PostPosted: Tue Feb 09, 2016 6:52 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2981
Location: Tampere, Finland
AlienX wrote:
thefox wrote:
It's very unfortunate that the value being written doesn't get passed to registerwrite().

So does that mean, there's absolutely no way to read the state of the APU on time?

Well, Bavi_H mentioned the method where you'd look at the instruction that presumably was doing the write (it's probably going to be STA, STX or STY). From that you can derive the register where the value is. This should be fairly reliable.

Passing the actual value being written would be trivially easy on FCEUX developer's side and would avoid the need for any hacks like that, but alas, they have not done it.

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


Top
 Profile  
 
PostPosted: Tue Feb 09, 2016 7:36 am 
Offline
Formerly AlienX
User avatar

Joined: Fri Apr 18, 2014 7:41 am
Posts: 133
Location: Bulgaria
OK, I'm executing Bavi_H's instructions, one by one, and they seem to be working well. However, I have encountered another problem, although this is probably due to my lack of knowledge of assembly programming and... well, programming in general. When displaying the values, found in the PC register, after using the memory.readbyte(memory.getregister("pc")) function, I can only see small numbers, like 96 or 20, or whatever. None of these look like they could be actual instructions and they only seem to change, when certain sound effects are being played, as if they're, more or less, pointers to the game's music and the different sound effects. :? Is there a way to extract information about the instruction and the values, that are being written, from this? Is there something I'm doing wrong?

_________________
Greetings! I'm That Bio Mechanical Dude and I like creating various stuff like movies, games and of course chiptunes!
You can check out my YouTube Channel.
You can also follow me on Twitter.


Top
 Profile  
 
PostPosted: Tue Feb 09, 2016 1:16 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5822
Location: Canada
thefox wrote:
Passing the actual value being written would be trivially easy on FCEUX developer's side and would avoid the need for any hacks like that, but alas, they have not done it.

I have this on my to-do list to figure out and implement, but I have other higher priority projects besides contributing to FCEUX right now, so might take me a while to get to it. If nobody else gets to it, I'll do it eventually.


Top
 Profile  
 
PostPosted: Tue Feb 09, 2016 2:58 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2981
Location: Tampere, Finland
AlienX wrote:
OK, I'm executing Bavi_H's instructions, one by one, and they seem to be working well. However, I have encountered another problem, although this is probably due to my lack of knowledge of assembly programming and... well, programming in general. When displaying the values, found in the PC register, after using the memory.readbyte(memory.getregister("pc")) function, I can only see small numbers, like 96 or 20, or whatever. None of these look like they could be actual instructions and they only seem to change, when certain sound effects are being played, as if they're, more or less, pointers to the game's music and the different sound effects. :? Is there a way to extract information about the instruction and the values, that are being written, from this? Is there something I'm doing wrong?

An instruction like STA $4002 would appear as 3 bytes: $8D $02 $40 ($8D = opcode of "STA absolute", $02 = lobyte of $4002, $40 = hibyte of $4002). At the time of the write the PC value returned by FCEUX may have already been modified past the instruction, so you might want to look at some of the preceding bytes.

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


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 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