not sure I understand bit 2 of $2000

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
User avatar
Kitty_Space_Program
Posts: 50
Joined: Mon Sep 21, 2020 7:42 am

not sure I understand bit 2 of $2000

Post by Kitty_Space_Program » Fri Dec 11, 2020 2:41 pm

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.

lidnariq
Posts: 10241
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: not sure I understand bit 2 of $2000

Post by lidnariq » Fri Dec 11, 2020 2:52 pm

Kitty_Space_Program wrote:
Fri Dec 11, 2020 2:41 pm
write to $2000 [...] #%1000100 and the background would appear on screen but just sideways.
The problem is that it doesn't wrap within the nametable. Instead it just keeps adding 32.

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.

User avatar
Quietust
Posts: 1684
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: not sure I understand bit 2 of $2000

Post by Quietust » Fri Dec 11, 2020 3:03 pm

lidnariq wrote:
Fri Dec 11, 2020 2:52 pm
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.
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).
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

User avatar
Kitty_Space_Program
Posts: 50
Joined: Mon Sep 21, 2020 7:42 am

Re: not sure I understand bit 2 of $2000

Post by Kitty_Space_Program » Fri Dec 11, 2020 4:03 pm

Quietust wrote:
Fri Dec 11, 2020 3:03 pm

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

Wait so then what’s the purpose of the vertical righting mode?

lidnariq
Posts: 10241
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: not sure I understand bit 2 of $2000

Post by lidnariq » Fri Dec 11, 2020 4:08 pm

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.

User avatar
Kitty_Space_Program
Posts: 50
Joined: Mon Sep 21, 2020 7:42 am

Re: not sure I understand bit 2 of $2000

Post by Kitty_Space_Program » Fri Dec 11, 2020 4:36 pm

lidnariq wrote:
Fri Dec 11, 2020 4:08 pm
It's just unlikely that your data is arranged such that it's useful to write more than 30 at a time.
Ow I see, ok. So I just need to increment the address stored at 2006(iirc) every 30 tiles.

User avatar
rainwarrior
Posts: 8000
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: not sure I understand bit 2 of $2000

Post by rainwarrior » Fri Dec 11, 2020 7:44 pm

Kitty_Space_Program wrote:
Fri Dec 11, 2020 4:36 pm
Ow I see, ok. So I just need to increment the address stored at 2006(iirc) every 30 tiles.
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.

User avatar
tokumaru
Posts: 11996
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: not sure I understand bit 2 of $2000

Post by tokumaru » Fri Dec 11, 2020 10:05 pm

rainwarrior wrote:
Fri Dec 11, 2020 7:44 pm
then doing two BIT $2007 instructions
Aren't $2007 reads unreliable if you're using the DMC channel? Just something to keep in mind.

User avatar
rainwarrior
Posts: 8000
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: not sure I understand bit 2 of $2000

Post by rainwarrior » Fri Dec 11, 2020 10:12 pm

tokumaru wrote:
Fri Dec 11, 2020 10:05 pm
rainwarrior wrote:
Fri Dec 11, 2020 7:44 pm
then doing two BIT $2007 instructions
Aren't $2007 reads unreliable if you're using the DMC channel? Just something to keep in mind.
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.

User avatar
Kitty_Space_Program
Posts: 50
Joined: Mon Sep 21, 2020 7:42 am

Re: not sure I understand bit 2 of $2000

Post by Kitty_Space_Program » Sat Dec 12, 2020 11:27 am

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:


User avatar
rainwarrior
Posts: 8000
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: not sure I understand bit 2 of $2000

Post by rainwarrior » Sat Dec 12, 2020 12:55 pm

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.

User avatar
Kitty_Space_Program
Posts: 50
Joined: Mon Sep 21, 2020 7:42 am

Re: not sure I understand bit 2 of $2000

Post by Kitty_Space_Program » Sat Dec 12, 2020 1:10 pm

Ok thank you I’ll give that ago.
rainwarrior wrote:
Sat Dec 12, 2020 12:55 pm
I 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.

User avatar
Kitty_Space_Program
Posts: 50
Joined: Mon Sep 21, 2020 7:42 am

Re: not sure I understand bit 2 of $2000

Post by Kitty_Space_Program » Sat Dec 12, 2020 3:42 pm

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:

User avatar
rainwarrior
Posts: 8000
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: not sure I understand bit 2 of $2000

Post by rainwarrior » Sat Dec 12, 2020 5:00 pm

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:

Code: Select all

A = (Y / 16) + Y
if A = 0 keep looping?
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:

Code: Select all

dec counter
bne decode
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.

unregistered
Posts: 1126
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: not sure I understand bit 2 of $2000

Post by unregistered » Mon Dec 14, 2020 6:33 pm

In your code like like this:

Code: Select all

  lda <nametableplaceholder+1
  clc
  adc #$01
  sta <nametableplaceholder+1
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:

Code: Select all

  inc <nametableplaceholder+1
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.

Post Reply