There are a few inconsistencies in your code that are bothering be a bit. For example, in the part where yoy set the PPU address before writing tiles, there's a comment that says "PPUADDR = $2000 ". That got me confused because the PPU address register is actually $2006, and in the rest of the code you are not using registers' names you are using their addresses ($2007, $2005, etc), so you should either use only their addresses, or give them all names, making sure that they point to the correct addresses.
Another problem is that I don't see any writes to register $2000 (PPUCTRL). There should be a write to it next to the $2005 writes, because the lower 2 bits of PPUCTRL have an important part in the scrolling too. Since you are using vertical mirroring, and your name tables are arranged side by side, there will be times when you will be showing the one on the left and there will be times when you'll be showing the one on the right, and you will need to use PPUCTRL to indicate that.
About calculating the target address for your columns: you will have to use the "Scroll_x" variable for that. One important thing to change is that since your level is longer than 256 pixels, that variable must be 16-bits large. I assume you know how to handle 16-bit values.
Anyway, the tiles are 8 pixels wide, so you must detect when the camera crosses an 8 pixel barrier in order to know when to draw a new column. Look at the binary numbers and you will see that 0 is %00000000, 7 is %00000111, and 8 is %00001000. If you pay attention, you'll see that numbers 1 through 7 have the 4th bit as 0, and only when the number becomes 8 that bit changes to 1. Because of that, that is the bit that will tells us that the scroll crosses an 8 pixel barrier. The code could look something like this:
Code: Select all
lda Scroll_x+0 ;load the lower byte of Scroll_x
pha ;save it to the stack
;UPDATE Scroll_x HERE
pla ;get the old Scroll_x
eor Scroll_x ;XOR it with the new Scroll_x
and #%00001000
beq +Skip
;DECODE A NEW COLUMN HERE
+Skip:
Once you have decided that a new column must be rendered, it's time to find out where in the level map this column is and where in the name tables it should be rendered to. Scroll_x will also help you with this.
Scroll_x tells you which part of the name tables should be displayed at the leftmost side of the screen, so if you you scrolled left, that's the column that has to be updated. If you scrolled right (to detect whether you scrolled right or left you have to compare the old Scroll_x to the new one and see which one is larger), you have to add 256 to Scroll_x to find which column needs updating, because the right side of the screen is 256 pixels to the right of the left side.
I don't know how your level map is stored, so it's up to you to convert Scroll_x to a format that allows you to read from it, but I can tell you about calculating the destination address in the name tables. Once you have defined the X coordinate of the column (it's either Scroll_x or Scroll_x + 256), you have to get rid of the lower 3 bits to convert it from pixel units to tile units. Then, the next 5 bits (a number between 0 and 31) will indicate what name table column to use. The next bit will tell you if you should write the column to the first name table ($2000) or to the second ($2400).
When setting the scroll, you have to write the lower byte of Scroll_x to $2005, and the first bit of the high byte to bit 0 of PPUCTRL, in order to select the name table where scrolling should start.
I know that's a lot of information, and I don't think I can make it any simpler. This stuff isn't so trivial, so if you are having a hard time with this maybe you should consider not using scrolling for your first project.