I'm writing to $2005.. but it seems like it interprets 0 to be in the middle of the name table, not the very top left
If I watch the scroll lines in FCEUD, the cross hatch starts out on the far left. then if I start scrolling by incrementing a variable and writing that to $2005, the crosshatch moves to the rightmost edge of the screen. But when the variable loops around to 0, the cross hatch does not move back to the far left but rather the center.
the same thing happens when I try vertical scrolling
am I totally missing something? I tried checking out the "skinny" scrolling documents but I didn't really understand the difference between writing to $2006 vs $2005 for scrolling.
You need to use bits 0,1 of $2000 to set the nametable scroll.
Is scrolling the very last thing you do before the screen starts rendering? Any writes to VRAM or pointer changes also acts as scrolls. Also make sure you are performing the scroll writes during Vblank (or during the dummy scanline before ppu clock #304). The top bits of 2000 also affect scrolling.
yes scrolling is the last thing i do before returning from the vblank interrupt
I tried updating $2000 when the vertical scroll reaches $F0 but when I set it to $00, no matter what i set $2000 to, it still goes back to the halfway point, not the very top of the nametable
also, I don't understand why the scroll will start out on the very far left and advance all the way across the screen, but then once it hits the right side, setting it to 0 only goes to the 1/2 way point. what changes?
i will try to put together a small test case with some code
edit: LOL of course it works in my test case.. i'll see what i'm doing differently.
edit2: ug of course it doesn't work in the main program. i think it has to do with the fact i'm updating the nametable at the same time
ok i got it working, but only if i don't make writes to PPUADDR. How do I reset the nametable after writing to PPUADDR? I write to PPUCTRL after PPUADDR to set the name table but it doesnt seem to make a difference
eit: got it finally! I realized i was only updating PPUCTRL at the screen boundary not every vblank
/me is still confused by those reg names.
PPUADDR=$2006 and PPUCTRL=$2000, right?
ANYanyway:
1) You don't need to write to $2006 for scrolling. In fact you shouldn't. The only time you need to do that is if you're splitting the screen or turning the PPU on late.
2) once you finish with ALL of your drawing and are done with $2006/$2007, then write to $2000 and twice to $2005 to set the scroll
3) once the scroll is set, you cannot touch $2006/$2007 or else you will screw up the scroll.
4) The scroll must be set before rendering starts. (dot 304 of the prerender line, iirc, is the cutoff time -- but ideally you'd have it done sooner than that)
edit - glad you hear you got it working! ^^
Quote:
/me is still confused by those reg names.
PPUADDR=$2006 and PPUCTRL=$2000, right?
i thought there were standard names.. should I not use them? but yeah you got them right
and i'm not using $2006 for scrolling, i'm using it to write to the nametable and change palettes
Quote:
edit - glad you hear you got it working! ^^
thanks for your help
I would stick with the hex values for referring to the registers. There aren't very many of them, and if you refer to them directly, pretty much everyone will know what you're talking about. And then in your code if you write to one of them without using an alias, you'll know 100% what exactly is going on.
They are more or less the commonly accepted names I guess. The thing is they only seem to be used by NES devers and not really by emu devers. So emu devers like myself aren't used to them.
tepples (I think) is a strong advocate of using those names. So whatever -- I figured out what you meant, it just took a little bit of thought on my part because it's not what I'm personally used to. Stick with whatever you're more comfortable with.
oh ok, it's cause you're a emudev guy that you're not as familiar with them
from a programming perspective I think it's always better to use constants instead of 'magic numbers' so i think i'll stick with them
To those arguing for raw register addresses, to be consistent you should code with .byte rather than assembly mnemonics, because then you know the real opcode
It makes sense that emulator authors aren't as apt to use symbolic names for the register addresses, because they often have only two or three occurrences of each register's address in the entire program, whereas a NES program has tens or hundreds of references. Also, an emulator is usually in a high-level language, so they stand out, while in assembly, complexity is higher so anything that reduces the load on the programmer is good.
blargg wrote:
To those arguing for raw register addresses, to be consistent you should code with .byte rather than assembly mnemonics, because then you know the real opcode
Oh, please
. It would actually be easier to spot register writes in your code if you use the raw addresses (at least I think). They stand out more, and they should as they should be rare compared to just writes to RAM. But that's just my opinion.
i think ideally almost all access with the registers would be done through macros and subroutines anyways so it wouldn't really matter :-p
though in practice i don't know how realistic this is...
Celius wrote:
It would actually be easier to spot register writes in your code if you use the raw addresses (at least I think). They stand out more
That's what syntax coloring is for. But unfortunately, too many text editors come with presets that recognize only i386 syntax, not 6502 syntax.
frantik: Your ideal is closer than some people might think, even on a 1.8 MHz 6502 at 60 frames per second. The only parts of an NES program that
need to touch hardware are the init code, read_pads(), update_sound(), and copy_transfer_buffers_to_vram().
tepples wrote:
too many text editors come with presets that recognize only i386 syntax, not 6502 syntax.
thats why I love UltraEdit.. you can define your own color highlighting. I could even add special highlighting to the registers if i wanted to
Quote:
frantik: Your ideal is closer than some people might think, even on a 1.8 MHz 6502 at 60 frames per second. The only parts of an NES program that need to touch hardware are the init code, read_pads(), update_sound(), and copy_transfer_buffers_to_vram().
good to know
i've got the init code and reading pads down.. now i have to work on using buffers to update the graphics
A big point of symbolic constants is to reduce the chance for error. Whereas mistyping/misremembering $2005 as $2006 is one key away, mistyping PPUSCROLL instead of PPUADDR is many keys away. One value of higher-level languages is to reduce errors by restricting what can be done, using context to determine the current things allowed. Whereas coding in raw machine code means that any byte value is valid, in asm you can only use mnemonics and directives. Symbolic constants are just an extension of this into the program itself.