I'm away from my computer, so all this is untested, I worked it out on scratch paper during lunch at work...
Ok, converting a nametable address to its attribute address, so let's look at the first attribute byte...
23c0 covers Nametable addresses...
2000-1, 2002-3
2020-1, 2022-3
2040-1, 2042-3
2060-1, 2062-3
The next attribute byte, 23c1, is the same except the $04 bit is set in addresses. Starting 2004-5, etc.
We need 3 bit from X coordinates, and 3 from Y coordinates.
Therefore, the low 3 bits of attribute table correspond to these bits of the low nametable address...
---1 11--
The next attribute table byte down from the top left is 23c8, is covers these nametable addresses...
2080-1, 2042-3
20a0-1, 20a2-3
20c0-1, 20c2-3
20e0-1, 20e2-3
You see the $80 bit of the low nametable address byte is the next bit we need. We also need two more, the lowest 2 bits from the high nametable byte.
1--- ---- low
---- --11 high
Heres some untested code...
(Note addr = low byte of address, addr+1 = high byte)
Code:
Lda addr
And #$1c ;mask 3 bits
Lsr a
Lsr a
;;;;Lsr a ;too many
Sta temp
Lda addr
And #$80 ; mask 1 bit
Asl a ;put it in carry flag
Lda addr+1
And #03 ;mask 2 bits
Rol a ;shift bit in from carry
Asl a
Asl a
Asl a
Clc
Adc temp
Ora #$c0
Sta attrib_addr
Bit $2002
Lda addr+1
Ora #03 ;high byte of attrib table
Sta $2006
Lda attrib_addr
Sta $2006
Lda $2007 ;junk
Lda $2007 ;data
Sta temp
;now decide which 2 bits to modify
;the $02 bit of low nametable address decides L/R
;the $40 bit of low nametable address decides Top/Bot
;bits are aligned 44332211 =
;1, 2
;3, 4
Lda addr
And #$40 ;top or bottom?
BNE BOTTOM
TOP:
Lda addr
And #02
BNE TOP_R
TOP_L:
Lda temp ;our data
And #$fc ; mask out bits
Sta temp
Lda new_bits ;in right 2 bit position
Ora temp
Sta temp
Jmp END
TOP_R:
Lda temp ;our data
And #$f3 ; mask out bits
Sta temp
Lda new_bits ;in right 2 bit position
Asl a
Asl a
Ora temp
Sta temp
Jmp END
BOTTOM:
Lda addr
And #02
BNE BOT_R
BOT_L:
Lda temp ;our data
And #$cf ; mask out bits
Sta temp
Lda new_bits ;in right 2 bit position
Asl a
Asl a
Asl a
Asl a
Ora temp
Sta temp
Jmp END
BOT_R:
Lda temp ;our data
And #$3f ; mask out bits
Sta temp
Lda new_bits ;in right 2 bit position
Clc
Ror a
Ror a
Ror a
Ora temp
Sta temp
;Jmp END
END: ;put new data in attrib table
Lda addr+1
Ora #03
Sta $2006
Lda attrib_addr
Sta $2006
Lda temp
Sta $2007
I think that's right. I'll check it when I get home.
_________________
nesdoug.com -- blog/tutorial on programming for the NES