APU Addresses in FCEUX?
Page 2 of 2

Author:  BioMechanical Dude [ Wed Feb 10, 2016 7:00 am ]
Post subject:  Re: APU Addresses in FCEUX?

And how exactly should I go about doing that? Reading from the PC register is the only way of getting any information about the code. Is there some kind of function, allowing to have a better look at the different bytes, without searching ROM addresses? (Also, just in case, this cannot happen with the use of the debugger. It all has to be done through the script) The FCEUX Lua help does not offer any explanation for that.

Author:  tokumaru [ Wed Feb 10, 2016 1:57 pm ]
Post subject:  Re: APU Addresses in FCEUX?

I have to say that using the PC to take a look at the code and find out which register was used in a write operation is a very interesting idea! It could be useful in a script that draws bounding boxes around the sprites, for example, so you could catch the sprite height and the page of RAM that was used for the DMA.

Author:  cpow [ Wed Feb 10, 2016 8:32 pm ]
Post subject:  Re: APU Addresses in FCEUX?

tepples wrote:
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.

Thanks for the shout-out, Tepples.
Yes, NESICIDE has annotations for every register of every supported mapper. Currently the list of supported mappers is fairly small but includes the most obvious ones.

Author:  Bavi_H [ Thu Feb 11, 2016 12:17 am ]
Post subject:  Re: APU Addresses in FCEUX?

AlienX wrote:
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.

I think sound.get itself is accessing the register values directly without any delay, but I could be wrong.

    (I have previously looked at the FCEUX source code of the lua sound.get function for another project. It looks like FCEUX uses an array called PSG to store the sound register values, and sound.get is just dumping values directly out of this array.)

But there might still be a problem of how to get the script to run the sound.get call when you want. That is, maybe emu.frameadvance, emu.registerbefore, emu.registerafter, or gui.register are introducing unwanted delays before sound.get ever runs.

Maybe you could use a memory.registerwrite to catch writes to addresses in the the sound register range, then in the callback function, just use sound.get to look at the sound register information.

If you still need to capture the exact address and value written, here is a start on that idea:

- - -

I originally thought when the memory.registerwrite triggers, the program counter would be at the beginning of the instruction that preforms the write, and you could just read that byte and next few bytes to reconstruct the address and value. But it appears when the memory.registerwrite triggers, the program counter is at the instruction after the write is preformed. That means we have to look back a few bytes and check if there is an instruction that makes sense.

I looked over the instruction set and made a list of instructions that can write to memory:


Some of these instructions have to read the current value from memory to modify it:


Since you can't read a useful value from the sound register addresses, the NES program is unlikely to use these instructions with the sound registers, so I reduced the list to the following:


Then I made a list of the addressing mode variations of these instructions that apply to a non-zeropage memory value:

opcode  bytes  instruction   pseudocode

  8C      3      STY MM       Mem[MM] := Y
  8D      3      STA MM       Mem[MM] := A
  8E      3      STX MM       Mem[MM] := X
  99      3      STA MM,Y     Mem[MM+Y] := A
  9D      3      STA MM,X     Mem[MM+X] := A

  81      2      STA (M,X)    Mem[ Mem{M+X} + 256*Mem{M+X+1} ] := A
  91      2      STA (M),Y    Mem[ Mem{M} + 256*Mem{M+1} + Y ] := A

{} = mod 256, [] = mod 65536

In "write catcher 1.lua" I print out the detected instructions. I used this script with a few NES ROMs to check if there were cases of ambiguous instruction possibilities or if I was missing a case. In the few ROMs I looked at, I didn't see any indirect addressing used with these sound register writes.

In "write catcher 2.lua", I print out the address and value that get written. For now, I didn't complete the cases for the indirect addressing modes. If you see indirect modes getting used in "write catcher 1.lua", then we'll need to fill out "write catcher 2.lua" with those cases.

write catcher [1.06 KiB]
Downloaded 67 times

Author:  BioMechanical Dude [ Thu Feb 11, 2016 5:26 am ]
Post subject:  Re: APU Addresses in FCEUX?

OK, I've tried some stuff out. Unfortunately, replacing frameadvance() and any other similar functions with event listeners didn't help. There's still delay. You might say, that the problem comes from the library I'm using, because it loads sound samples, but the delay speed remains consistent. If FCEUX really isn't waiting for the frame to end, before updating the information for sound.get(), then I really don't know what the problem is anymore.

The last option I have is the write catcher, which works great on its own (Thanks, btw). I do however have some questions about FCEUX and Lua, in general. Is there a way to have a loop outside the functions, which doesn't pause the emulator? In order to get the full information about a note, I need both the low period and the high period values (addresses $4002 and $4003, for instance), so I need the two writes to be done first. Because you can never predict which address is going to be written to first, I was thinking of having some kind of counter, that would reach a certain value, when the two writes are done. However, I need to be able to constantly check the state of the counter and any code that's not in a loop will be executed only once. So... what can I do? I haven't found any information about native event listeners in Lua and FCEUX only provides options for the game's addresses.

Author:  feos [ Sat Jul 30, 2016 11:04 am ]
Post subject:  Re: APU Addresses in FCEUX?

Register values are available as a part of RAM now (hex editor, debugger, probably other tools too), in the recent release. Does setting breakpoints to those writes work for you guys?

Page 2 of 2 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group