It is currently Wed May 22, 2019 3:37 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Thu Mar 07, 2019 8:15 pm 
Offline
User avatar

Joined: Thu Aug 13, 2015 4:40 pm
Posts: 405
Location: Rio de Janeiro - Brazil
So... Scroll position cannot be read by looking at some address of CPU or PPU RAM?
Also, your note about when to read the registers, you're talking about $2000 and $2001? I think I'm reading it when the emulator is paused, the same moment any memview file prompt popup is launched. So far with my tests it seems to be working ok, but it could be that it's loading at some random moment and I'm lucky. I'm just using default memview behavior, it seems to be fine.

Moving on:

I'm having a really hard time understanding the code. I've only found two instances of the string "2005" on ppu.cpp.
Code:
ARead[x + 5] = A200x;
BWrite[x + 5] = B2005;


I don't know what to make of this. What is "A200x"?

Also, when programming a game in ca65 I've learned horizontal scroll has two important values: the selected nametable, as defined by the two least significant bits of PPUCTRL register, and a value of 0-255 to be written to $2005 that defines the pixel position of the scroll relative to the selected nametable. Is that equivalent to what I'm looking for in the source code? I ask this because the wiki talks about fine and coarse scroll values, which is confusing me. Source: http://wiki.nesdev.com/w/index.php/PPU_scrolling

Code:
PPU internal registers

v
Current VRAM address (15 bits)
t
Temporary VRAM address (15 bits); can also be thought of as the address of the top left onscreen tile.
x
Fine X scroll (3 bits)

The 15 bit registers t and v are composed this way during rendering:
yyy NN YYYYY XXXXX
||| || ||||| +++++-- coarse X scroll
||| || +++++-------- coarse Y scroll
||| ++-------------- nametable select
+++----------------- fine Y scroll


It took me a long time to understand this. So the PPU has a register called "x". So... I need registers v and x?

ppu.cpp has this function, but I don't understand how it's used
Code:
void ppu_getScroll(int &xpos, int &ypos) {
   if (newppu) {
      ypos = ppur._vt * 8 + ppur._fv + ppur._v * 256;
      xpos = ppur._ht * 8 + ppur.fh + ppur._h * 256;
   } else {
      xpos = ((RefreshAddr & 0x400) >> 2) | ((RefreshAddr & 0x1F) << 3) | XOffset;

      ypos = ((RefreshAddr & 0x3E0) >> 2) | ((RefreshAddr & 0x7000) >> 12);
      if (RefreshAddr & 0x800) ypos += 240;
   }
}

_________________
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!


Top
 Profile  
 
PostPosted: Thu Mar 07, 2019 8:25 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7461
Location: Canada
B2005 is defined here

No, scroll isn't just stored in RAM anywhere, it's an internal PPU thing and intimately tied up with the PPU address (written through $2006) as well. That wiki page you linked should explain, hopefully.


Top
 Profile  
 
PostPosted: Fri Mar 08, 2019 6:44 am 
Offline
User avatar

Joined: Thu Aug 13, 2015 4:40 pm
Posts: 405
Location: Rio de Janeiro - Brazil
My C++ knowledge is too limited. It's too abstract to me right now. DECLFW is defined as "void x (uint32 A, uint8 V)" in fceu.h. I have no idea what that means. Shouldn't A be the accumulator, therefore uint8?

Anyway, B2005 only seems to be ever used to initialize PPU, so that doesn't seem to be useful. I tried to retrieve PPUGenLatch and it always came out as 0. I don't know how to access ppu.cpp's "V" from memview.cpp even though I've included ppu.h. I can't include ppu.cpp, it gives a random error elsewhere.

There's this, but I don't know how to access those vars from memview.cpp. I tried searching for how savestate does it, but I couldn't either. I think I'm going to give up for now.
Code:
struct PPUREGS {
   //normal clocked regs. as the game can interfere with these at any time, they need to be savestated
   uint32 fv;   //3
   uint32 v;   //1
   uint32 h;   //1
   uint32 vt;   //5
   uint32 ht;   //5

   //temp unlatched regs (need savestating, can be written to at any time)
   uint32 _fv, _v, _h, _vt, _ht;

   //other regs that need savestating
   uint32 fh;   //3 (horz scroll)
   uint32 s;   //1 ($2000 bit 4: "Background pattern table address (0: $0000; 1: $1000)")

_________________
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!


Top
 Profile  
 
PostPosted: Fri Mar 08, 2019 6:03 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7461
Location: Canada
A is for "address" and V is for "value", in that function.

Though I think really you found a better interface already in ppu_getScroll, which already seems designed to convert the current register state into convenient pixel scroll coordinates.

Code:
int x,y;
ppu_getScroll(x, y);
// x add y now equal to scroll positions


Edit: made a typo in the code.


Last edited by rainwarrior on Fri Mar 08, 2019 7:00 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Fri Mar 08, 2019 6:50 pm 
Offline
User avatar

Joined: Thu Aug 13, 2015 4:40 pm
Posts: 405
Location: Rio de Janeiro - Brazil
40 minutes after reading your message, I think I got it. At least looking at the output file binary seems to be producing numbers different than zero. It was giving me an error about const params and pointers I assume (from my error research), though I don't fully understood it. So after trying some things semi blindly, this is what worked:

Code:
int scx = 0;
int scy = 0;
int *scxptr = &scx;
int *scyptr = &scy;
ppu_getScroll( *scxptr, *scyptr);
bar[0x4103] = *scyptr; // this is the binary file address I chose for scroll y
bar[0x4102] = *scxptr; // this is the binary file address I chose for scroll x


Thanks you very much, importing dumps is getting very robust, at least for games that don't change much graphics mid-frame.

_________________
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!


Top
 Profile  
 
PostPosted: Fri Mar 08, 2019 7:02 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7461
Location: Canada
Sorry, I made a typo above. There should not have been an & in front of x and y.

You don't need to make a pointer to a reference and then dereference them like you're doing, you can just use the two ints directly. The & in the function's declaration automatically references them and makes them available for output.


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: No registered users and 10 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