Edit: tepples has chimed in with useful info too, on both subjects.
vivi168 wrote:
I must admit I was a little lost here.
Why does long addressing only work in mode 20/LoROM?
Long addressing works in any mode. However, mode 20 has the memory map/layout where the lower 32KB of most banks (but not all) your code runs in are mirrors of bank $00 -- that way, no matter what bank your code is running in, you can do
sta $2118 and it'll do exactly what you expect.
In mode 21, the situation is a bit different. I worry that by describing this memory map that you're going to completely get confused and lose focus on accomplishing your goal, so I'm reluctant to describe it. This is a crappy one-paragraph description with stuff omitted but this is what's important: banks $C0-FF are full 64KB of ROM, that is to say they do not have the lower 32KB of the bank mirrored to $00, so if your code runs out of $C0-FF then
sta $2118 will do nothing (while
sta $002118 would work fine). Mode 21 does have some banks that have the lower 32KB mirrored from $00 -- such as banks $80-BF and $01-3F. (The latter is needed because all the CPU vectors (ex. reset, nmi, irq, cop, etc.) are read from bank $00 by the CPU itself) Banks $80-FF support high speed mode, too. (I'm not going to get into describing that) Banks $40-7D (yes, 7D) mirror $C0-FD, I believe.
I would love to attach pictures showing you the topologies but I have intentionally gone back and removed all screenshots of the dev manual I've uploaded + don't post them any more out of concern of Nintendo cracking down on IP. That's a separate subject not for this thread please.
In general, I always tell people to stick with mode 20 unless you know right up front that you're going to need TONS of ROM space -- odds are you aren't.
vivi168 wrote:
As for TCD, I've made some research, it transfers the the 16 bits in of the accumulator to the Direct Page Register I think, but I'm not exactly sure what that means?
Does it affect which page/bank you access? For example instead of accessing Zero Page, you access Page 02?
Do you understand zero page from 6502/65c02? If so, then understanding DP is easy!
In 6502/65c02 zero page refers to memory from $0000 to $00FF, hence the term "zero page". Page 1 would be $0100-01FF, page 2 $0200-02FF, etc.
The D register on the 65816 lets you relocate that "zero page" to
anywhere within bank $00. D is a 16-bit register. So while
lda $20 would, on 6502, read from $0020, on the 65816 it could read from anywhere in bank $00 depending on what D is set to. Code examples to explain it:
Code:
lda #$0000 / tcd / lda $40 ; reads 16-bit value from bank $00, $0000-0001 (i.e. identical to 6502/65c02's zero page)
lda #$0200 / tcd / lda $40 ; reads 16-bit value from bank $00, $0240-0241
lda #$1100 / tcd / lda $18 ; reads 16-bit value from bank $00, $1118-1119
lda #$1f6f / tcd / lda $10 ; reads 16-bit value from bank $00, $1f7f-1f80 with penalty
One thing to keep in mind: there is a 1 cycle penalty on DP addressing operations if the low byte of D is non-zero (e.g. $xx66, $xx20, etc.). So in general you should ensure it's "page-aligned" (e.g. D=$xx00).
Now you see how this trick can be used to potentially allow for MMIO register access using direct page by doing
lda #$2100 / tcd.
However,
as I stated in an earlier post's last paragraph, ca65/ld65 does not have good support for relocatable direct page on 65816. It does not "decently" handle understanding the situation where a programmer relocates D from $0000 (the default). So, if you use ca65, you should stick with D=$0000 to avoid severe pains, else if changing it always put it back to D=$0000 when done. There is a separate thread on this forum discussing this matter, so if you really find you need to use relocatable DP, look for the thread / ask and one of us can link it.
Quote:
So to clarify, first of all, I've set $2105 (BGMODE) to $01 (bg mode 1, tile size 8). and $2107 (BG1SC) is set to $10 (only one 32x32 tilemap).
At the beginning, I first load the tilemap from the ROM to PPU via DMA. Then when going left and right, I scroll the background. For now, it only wraps back.
What I'm looking to do, is fetch a column of another tilemap in the ROM and write it over a column of the tilemap in the PPU. (So it gives the illusion of a longer level, like the GIF tepples posted). From what I've read in this thread, it might be a good idea to first transfer it to the WRAM, and then copy the column I need from the WRAM to the PPU.
Right -- this is exactly what I was describing with my code, etc.. psychopathicteen came in here to describe something that relates to earlier posts in the thread, talking about how you actually handle the whole "camera situation". Those posts:
viewtopic.php?p=234954#p234954 (but not exactly -- Oziphantom describes something important here!)
viewtopic.php?p=234955#p234955Implementing what's described in those would be the *next* phase for you to try to accomplish *after* you accomplish what you're currently doing. (This is a common problem with this forum, BTW -- people often will show up and de-rail a training exercise with stuff and the user ends up confused. Forums are not good forms of teaching, IMO, at least in comparison to, say, having a classroom with students listening to you and focused directly on things one step at a time. There are only a few here on this forum who, IMO, are good teachers.)
Again to repeat myself: keep with what you're doing right now. Work on getting routine(s) that can update the PPU RAM in columns and rows (particularly the 4 edges of the screen). From there, you can get a better grasp of what needs to be done. Oziphantom's post though is pretty good. If you need to make 4 separate routines at first (for each edge), then do it that way. It's OK! You can/will consolidate them later once you get a better understanding of it. :-)
Make sure you get yourself a SNES emulator with a good debugger too, ex. bsnes-plus, BTW. You are going to need it, I promise you, because you're going to need to see what's actually in PPU RAM (to ensure your routines are writing to the correct addresses) and in WRAM as well.