APU Addresses in FCEUX?

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

User avatar
BioMechanical Dude
Formerly AlienX
Posts: 137
Joined: Fri Apr 18, 2014 7:41 am
Location: Bulgaria

APU Addresses in FCEUX?

Post by BioMechanical Dude »

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.
User avatar
freem
Posts: 176
Joined: Mon Oct 01, 2012 3:47 pm
Location: freemland (NTSC-U)
Contact:

Re: APU Addresses in FCEUX?

Post by freem »

from the wiki:
(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).
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: APU Addresses in FCEUX?

Post by dougeff »

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
lidnariq
Posts: 11430
Joined: Sun Apr 13, 2008 11:12 am

Re: APU Addresses in FCEUX?

Post by lidnariq »

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

Re: APU Addresses in FCEUX?

Post by tepples »

Would a "☑ Show last value written to write-only registers" checkbox confuse?
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: APU Addresses in FCEUX?

Post by rainwarrior »

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

Re: APU Addresses in FCEUX?

Post by tepples »

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.
Bavi_H
Posts: 193
Joined: Sun Mar 03, 2013 1:52 am
Location: Texas, USA
Contact:

Re: APU Addresses in FCEUX?

Post by Bavi_H »

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.
User avatar
BioMechanical Dude
Formerly AlienX
Posts: 137
Joined: Fri Apr 18, 2014 7:41 am
Location: Bulgaria

Re: APU Addresses in FCEUX?

Post by BioMechanical Dude »

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.
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: APU Addresses in FCEUX?

Post by thefox »

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: fo.aspekt.fi
User avatar
BioMechanical Dude
Formerly AlienX
Posts: 137
Joined: Fri Apr 18, 2014 7:41 am
Location: Bulgaria

Re: APU Addresses in FCEUX?

Post by BioMechanical Dude »

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.
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: APU Addresses in FCEUX?

Post by thefox »

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: fo.aspekt.fi
User avatar
BioMechanical Dude
Formerly AlienX
Posts: 137
Joined: Fri Apr 18, 2014 7:41 am
Location: Bulgaria

Re: APU Addresses in FCEUX?

Post by BioMechanical Dude »

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.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: APU Addresses in FCEUX?

Post by rainwarrior »

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.
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: APU Addresses in FCEUX?

Post by thefox »

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: fo.aspekt.fi
Post Reply