It is currently Sat Dec 16, 2017 8:02 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Wed Feb 10, 2016 7:00 am 
Offline
Formerly AlienX
User avatar

Joined: Fri Apr 18, 2014 7:41 am
Posts: 137
Location: Bulgaria
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.

_________________
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: Wed Feb 10, 2016 1:57 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10166
Location: Rio de Janeiro - Brazil
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.


Top
 Profile  
 
PostPosted: Wed Feb 10, 2016 8:32 pm 
Offline
NESICIDE developer
User avatar

Joined: Mon Oct 13, 2008 7:55 pm
Posts: 1058
Location: Minneapolis, MN
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.


Top
 Profile  
 
PostPosted: Thu Feb 11, 2016 12:17 am 
Offline

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

ASL DEC INC LSR ROL ROR STA STX STY

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

ASL DEC INC LSR ROL ROR

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:

STA STX STY

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

Code:
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.


Attachments:
write catcher scripts.zip [1.06 KiB]
Downloaded 53 times
Top
 Profile  
 
PostPosted: Thu Feb 11, 2016 5:26 am 
Offline
Formerly AlienX
User avatar

Joined: Fri Apr 18, 2014 7:41 am
Posts: 137
Location: Bulgaria
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.

_________________
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: Sat Jul 30, 2016 11:04 am 
Offline
User avatar

Joined: Tue Apr 19, 2011 11:26 am
Posts: 106
Location: RU
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?


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: sdm, Yahoo [Bot], zxbdragon and 11 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