not sure I understand bit 2 of $2000
Moderator: Moderators
- Kitty_Space_Program
- Posts: 50
- Joined: Mon Sep 21, 2020 7:42 am
not sure I understand bit 2 of $2000
so, I'm trying to convert my game to load levels from top left to bottom left and to the right from there so I could countably update namable as I'm scrolling without updating full a nametable constantly. I figured that to get it to display that, all I'd need to do is change every write to $2000 from #%10000000 to #%1000100 and the background would appear on screen but just sideways. after doing this for every $2000 write, I got a different color palette for the sprites and no background at all, though different emulators had different backgrounds. Obviously I'm missing something here, but I can't seem to find information on it outside of the ppudata page on the wiki. Is there something else I need to do? obviously I'll need to change some code in decoding metatiles, but I'd think it would at least load the tiles themselves. Sorry if this is a dumb question, I just can't figure out what the processor needs me to do to get it to load vertically. Thank you for any help you can provide.
Re: not sure I understand bit 2 of $2000
The problem is that it doesn't wrap within the nametable. Instead it just keeps adding 32.Kitty_Space_Program wrote: ↑Fri Dec 11, 2020 2:41 pmwrite to $2000 [...] #%1000100 and the background would appear on screen but just sideways.
When you add 1, 31 (coordinate 31,0)+1=32 (coordinate 0,1), but 32×31 (coordinate 0,31)+32 is 1024 (coordinate 0,0 of the next nametable), not the 33 (coordinate 1,0) that you want it to be.
You "just" need to write new values to PPUADDR before each set of bytes you send.
Re: not sure I understand bit 2 of $2000
There's also the fact that nametables are only 30 tiles tall, so the (x,y) coordinates 0,30 and 0,31 are both within the attribute table; as such, writing a continuous stream wouldn't work anyways (unless you actually wanted to write attribute bytes too).lidnariq wrote: ↑Fri Dec 11, 2020 2:52 pmWhen you add 1, 31 (coordinate 31,0)+1=32 (coordinate 0,1), but 32×31 (coordinate 0,31)+32 is 1024 (coordinate 0,0 of the next nametable), not the 33 (coordinate 1,0) that you want it to be.
You "just" need to write new values to PPUADDR before each set of bytes you send.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
P.S. If you don't get this note, let me know and I'll write you another.
- Kitty_Space_Program
- Posts: 50
- Joined: Mon Sep 21, 2020 7:42 am
Re: not sure I understand bit 2 of $2000
Wait so then what’s the purpose of the vertical righting mode?
Re: not sure I understand bit 2 of $2000
You were correct the first time: it's for uploading columns of tiles. It's just unlikely that your data is arranged such that it's useful to write more than 30 at a time.
- Kitty_Space_Program
- Posts: 50
- Joined: Mon Sep 21, 2020 7:42 am
- rainwarrior
- Posts: 8000
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: not sure I understand bit 2 of $2000
If you're in vertical column mode you can read $2007 to increment the position 32 bytes without writing anything. If you're in vertical arrangement (horizontal mirroring) and you want to continue to the next nametable after the first 30, you could try writing to the mirrored table at $2400, then doing two BIT $2007 instructions (i.e. +64), then you can continue with the next 30 which will be at the top of the $2800 nametable now.Kitty_Space_Program wrote: ↑Fri Dec 11, 2020 4:36 pmOw I see, ok. So I just need to increment the address stored at 2006(iirc) every 30 tiles.
Re: not sure I understand bit 2 of $2000
Aren't $2007 reads unreliable if you're using the DMC channel? Just something to keep in mind.
- rainwarrior
- Posts: 8000
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: not sure I understand bit 2 of $2000
Hmm, that's a good point. If you're playing DPCM samples at the time, using a read instruction to increment will be slightly unreliable, occasionally getting an extra increment. If you're using DPCM, you might as well just write to $2006 twice to jump to the new address instead.
- Kitty_Space_Program
- Posts: 50
- Joined: Mon Sep 21, 2020 7:42 am
Re: not sure I understand bit 2 of $2000
I've gotten it to load (ie. not have a flashing screen and showing the sprite, though it isn't showing the background at all), but for some reason, its changed my sprite's color palettes as well, I'm not sure why. Here's my code in case I missed anything obvious or did that math wrong.
Code: Select all
getreadyfornametable1:
bit $2002
lda #$20; sets 2000 as the name table were using
sta $2006
lda #$00
sta $2006
tay
decode:
ldx metaworlddata,y
;top left
lda topleft,x
sta $2007
;bottom left
lda bottomleft,x
sta $2007
iny
tya
and #$0f
cmp #$00
bne decode
jsr nextrow
secondrow:
sty <nametableplaceholder
tya
sec
sbc #$10
tay
decode2:;secondrow stored in same metatile data
ldx metaworlddata,y
lda topright,x
sta $2007
lda bottomright,x
sta $2007
iny
cpy <nametableplaceholder
bne decode2
jsr nextrow
cpy #$f0
beq donewithnametableset
jmp decode
nextrow:
bit $2007 ;change later if using dpcm
bit $2007
rts
donewithnametableset:
- rainwarrior
- Posts: 8000
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: not sure I understand bit 2 of $2000
I think I misunderstood the intent, sorry. I thought you wanted to continue updating a column onto the next nametable below, for vertical scrolling, but you're actually trying to update two adjacent columns of the same nametable? My suggestion to read $2007 wasn't appropriate for this, just store the address of the next column into $2006 instead.
What you have right now is going to write down the leftmost column of the $2000 nametable, then the $2400 one, then the $2800 one, then the $2C00 one, then it will keep rolling through $3000, etc. eventually overwriting palettes, then going through CHR (which if it's ROM won't change anything) and then finally come back through $2000 and keep looping over those same left columns.
(If you open Mesen and put a breakpoint on writes to $2007 you could watch in the nametable viewer as it writes tile by tile to the nametable, which might help visually understand.)
Keep track of your column start, initially = $2000. Add 1 to it after each column ($2001, $2002, $2003, etc.) and write that to $2006, rather than the bit $2007 thing I suggested.
What you have right now is going to write down the leftmost column of the $2000 nametable, then the $2400 one, then the $2800 one, then the $2C00 one, then it will keep rolling through $3000, etc. eventually overwriting palettes, then going through CHR (which if it's ROM won't change anything) and then finally come back through $2000 and keep looping over those same left columns.
(If you open Mesen and put a breakpoint on writes to $2007 you could watch in the nametable viewer as it writes tile by tile to the nametable, which might help visually understand.)
Keep track of your column start, initially = $2000. Add 1 to it after each column ($2001, $2002, $2003, etc.) and write that to $2006, rather than the bit $2007 thing I suggested.
- Kitty_Space_Program
- Posts: 50
- Joined: Mon Sep 21, 2020 7:42 am
Re: not sure I understand bit 2 of $2000
Ok thank you I’ll give that ago.
That’s the end goal(but for horizontal scrolling), but for now I’m trying to make it so I can load the level, then worry about updating new columns later. I was thinking that you had to pick one mode or the other and the pup would interpret the data in that way. I guess I could just load the level horizontally, and then update the columns vertically as the player moves.
edit: I've realized that won't work, since I'm trying to keep level data as a string of numbers rather than having a bunch of individual screens. going fully vertical seems like the best way to do this.
rainwarrior wrote: ↑Sat Dec 12, 2020 12:55 pmI think I misunderstood the intent, sorry. I thought you wanted to continue updating a column onto the next nametable below, for vertical scrolling,
That’s the end goal(but for horizontal scrolling), but for now I’m trying to make it so I can load the level, then worry about updating new columns later. I was thinking that you had to pick one mode or the other and the pup would interpret the data in that way. I guess I could just load the level horizontally, and then update the columns vertically as the player moves.
edit: I've realized that won't work, since I'm trying to keep level data as a string of numbers rather than having a bunch of individual screens. going fully vertical seems like the best way to do this.
- Kitty_Space_Program
- Posts: 50
- Joined: Mon Sep 21, 2020 7:42 am
Re: not sure I understand bit 2 of $2000
ok so after updating it, There is still the problem of the sprites palettes being different, and the screen flashes different colors ad is real gtichy but eventually shows the background, though every other column is misaligned by two more than the one two before and the rest are 2 above where they should be, and some seem randomly placed,. To make sure my data is formatted write, i have it written out in rows of 15 (that is, counting from 1 in decimal 15) and is 32 wide (for both name tables. I also tried adding another row case that was the problem, but it just changed the color palette on my sprites. not sure there.
Code: Select all
lda #$20
sta <nametableplaceholder
getreadyfornametable1:
bit $2002
lda <nametableplaceholder; sets 2000 as the name table were using
sta $2006
lda <nametableplaceholder+1
sta $2006
tay
decode:
ldx metaworlddata,y
lda topleft,x
sta $2007
lda bottomleft,x
sta $2007
iny
tya
modof0f:
and #$f0
ror a
ror a
ror a
ror a
clc
sta <nibblehighbyteholder ;this finds if y is divisible by 0f, i.e. mod 0 by taking the high nibble and adding to low nibble, 1+e=f 2+d=f &c.
tya
adc <nibblehighbyteholder
bne decode
sty <yplaceholder
lda <nametableplaceholder+1
clc
adc #$01
sta <nametableplaceholder+1
bcc dontaddtohighbyte
lda <nametableplaceholder
clc
adc #$01
sta <nametableplaceholder
cmp #$28
beq donewithnametableset
dontaddtohighbyte:
tya
sec
sbc #$0f
tay
bit $2001
lda <nametableplaceholder
sta $2006
lda nametableplaceholder+1
sta $2006
decode2:
ldx metaworlddata,y
lda topright,x
sta $2007
lda bottomright,x
sta $2007
iny
cpy <yplaceholder
bne decode2
lda <nametableplaceholder+1
clc
adc #$01
sta <nametableplaceholder+1
bcc dontaddtohighbyte2
lda <nametableplaceholder
clc
adc #$01
sta <nametableplaceholder
cmp #$28
beq donewithnametableset
dontaddtohighbyte2:
jmp getreadyfornametable1
donewithnametableset:
- rainwarrior
- Posts: 8000
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: not sure I understand bit 2 of $2000
Some thoughts:
1.
In modof0f the first ror is done without the carry flag having been established. I think you should use lsr instead which will always shift in a 0 to the high bit, rather than whatever was in the carry flag like ror does.
I'm not sure I understand what that code is doing, though. It looks like, after each byte, ignorring the ROR vs. LSR issue:
That doesn't look like a remainder modulo 15 to me?
I'd suggest just setting some counter variable to 15 at the start of the loop, and instead of the whole modof0f thing do:
I don't think you really need to try dividing/modulo Y, just count to 15 and go to the next row.
2.
I would expect nametableplaceholder+0 to be always equal to $20 across the whole screen, whenever you're copying it to $2006, however it looks like you're incrementing it for each column?
Each column of the screen starts at PPU $2000, $2001, $2002... the high byte won't be changing here.
1.
In modof0f the first ror is done without the carry flag having been established. I think you should use lsr instead which will always shift in a 0 to the high bit, rather than whatever was in the carry flag like ror does.
I'm not sure I understand what that code is doing, though. It looks like, after each byte, ignorring the ROR vs. LSR issue:
Code: Select all
A = (Y / 16) + Y
if A = 0 keep looping?
I'd suggest just setting some counter variable to 15 at the start of the loop, and instead of the whole modof0f thing do:
Code: Select all
dec counter
bne decode
2.
I would expect nametableplaceholder+0 to be always equal to $20 across the whole screen, whenever you're copying it to $2006, however it looks like you're incrementing it for each column?
Each column of the screen starts at PPU $2000, $2001, $2002... the high byte won't be changing here.
-
- Posts: 1126
- Joined: Thu Apr 23, 2009 11:21 pm
- Location: cypress, texas
Re: not sure I understand bit 2 of $2000
In your code like like this:
The inc instruction would help you with readability and increase your code’s speed.
Since you don’t use the accumulator’s value after the add (inc increments the value at the memory location; nothing is ever loaded into the accumulator), this code could substitute for those 4 lines: Yes, inc <n takes 5 cycles, but your code section quoted above takes 10 cycles.
And changing my code that way, reduced some of the on-screen craziness.
Though, my screen, in the beginning, was at an extreme level of crazy.
Code: Select all
lda <nametableplaceholder+1
clc
adc #$01
sta <nametableplaceholder+1
Since you don’t use the accumulator’s value after the add (inc increments the value at the memory location; nothing is ever loaded into the accumulator), this code could substitute for those 4 lines:
Code: Select all
inc <nametableplaceholder+1
And changing my code that way, reduced some of the on-screen craziness.
