how to write to individual bits of a byte
Moderator: Moderators
how to write to individual bits of a byte
Hi!
I'm trying to use my arduino to send bytes to the nes through the joypad port.
how would I write the button states to an 8 bit value on each strobe?
I'm basically trying to perform the nes asm equivalent of arduino's bitWrite command.
Sorry if it's a stupid question, thanks in advance!
Alex
I'm trying to use my arduino to send bytes to the nes through the joypad port.
how would I write the button states to an 8 bit value on each strobe?
I'm basically trying to perform the nes asm equivalent of arduino's bitWrite command.
Sorry if it's a stupid question, thanks in advance!
Alex
-
doppelganger
- Posts: 183
- Joined: Tue Apr 05, 2005 7:30 pm
To set bits, use ORA:
lda somevalue
ora #%00100100 ;sets bits 5 and 2, leaves the rest alone
sta somevalue
To clear bits, use AND:
lda somevalue
and #%11011011 ;clears bits 5 and 2, leaves the rest alone
sta somevalue
To toggle bits, use EOR:
lda somevalue
eor #%00100100 ;clears bits 5 and 2 if they were set, and vice versa
sta somevalue ;and leaves the rest alone
Alternatively, you could LDA the bit and AND/ORA/EOR the memory location. It's up to you.
lda somevalue
ora #%00100100 ;sets bits 5 and 2, leaves the rest alone
sta somevalue
To clear bits, use AND:
lda somevalue
and #%11011011 ;clears bits 5 and 2, leaves the rest alone
sta somevalue
To toggle bits, use EOR:
lda somevalue
eor #%00100100 ;clears bits 5 and 2 if they were set, and vice versa
sta somevalue ;and leaves the rest alone
Alternatively, you could LDA the bit and AND/ORA/EOR the memory location. It's up to you.
^ Good explanation!
And here's a link on how to read the controllers. I'd say the easiest way to read them would be to shift the $4016 register after resetting it, then shift a, after 7 more times, A will have the controllers status inside it then you just store it in RAM and RTS to your main program, assuming your controller read is a subroutine, Since it should be.
Here's a site that has the buttons for each bit value.
http://fms.komkon.org/EMUL8/NES.html#LABI
And here's a link on how to read the controllers. I'd say the easiest way to read them would be to shift the $4016 register after resetting it, then shift a, after 7 more times, A will have the controllers status inside it then you just store it in RAM and RTS to your main program, assuming your controller read is a subroutine, Since it should be.
Here's a site that has the buttons for each bit value.
http://fms.komkon.org/EMUL8/NES.html#LABI
-
doppelganger
- Posts: 183
- Joined: Tue Apr 05, 2005 7:30 pm
Re: how to write to individual bits of a byte
And for my next trick, how to check individual bits of a byte that aren't bits 7 or 6 with the BIT instruction.
lda %00100100 ;branches if either bit 5 or 2 are set
bit somevalue
bne somewhere
lda %00100100 ;branches if either bit 5 or 2 are set
bit somevalue
bne somewhere
Be whatever the situation demands.
Re: how to write to individual bits of a byte
Using BIT here doesn't really have any benefits over using AND, unless the mask (%00100100) happens to be some magic value that can be reused later in the code (and even then, the benefit is negligible).doppelganger wrote:And for my next trick, how to check individual bits of a byte that aren't bits 7 or 6 with the BIT instruction.
lda %00100100 ;branches if either bit 5 or 2 are set
bit somevalue
bne somewhere
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
Re: how to write to individual bits of a byte
BIT is more useful (sometimes) when the value you're testing is in A and you don't want to modify it, like this:
LDA somevalue
BIT #%00100100
BNE somewhere
In fact, AFAIK that's the only difference between BIT and AND - AND stores the result in A, wiping out the original value. If the result of the AND is 0 during a BIT instruction, then the Z flag is set. Also, outside of immediate addressing, BIT will also copy bit 7 into the N flag and bit 6 into the V flag, so it's an easy way to branch based on whether either bit is set.
LDA somevalue
BIT #%00100100
BNE somewhere
In fact, AFAIK that's the only difference between BIT and AND - AND stores the result in A, wiping out the original value. If the result of the AND is 0 during a BIT instruction, then the Z flag is set. Also, outside of immediate addressing, BIT will also copy bit 7 into the N flag and bit 6 into the V flag, so it's an easy way to branch based on whether either bit is set.
Re: how to write to individual bits of a byte
BIT # works only on CMOS chips, such as those in the Lynx, TG16, Super NES, Apple IIc and IIGS, and late Apple IIe. On the original 6502, seen in Atari 2600/5200/7800, Commodore 64, Apple II/II+/III/IIe, and NES, BIT # is a 2-byte no-op.
Re: how to write to individual bits of a byte
My bad, I should have known that being a C64 guy. Looks like I'm getting a little rusty 
Re: how to write to individual bits of a byte
I found this a few weeks ago and thought it was pretty cool; if you want to take two bytes, A and B, and create a byte C where C has bits from A and bits from B, here's how you do it:
This is a little better than how you'd do it otherwise:
I found this trick when looking up stuff for the ZX Spectrum, and this was pretty common to do on the z80.
Code: Select all
LDA byteA
EOR byteB
AND #(for each bit, 1 means a bit from A, 0 means a bit from B)
EOR byteBCode: Select all
LDA byteA
AND #(the bits you want to keep)
STA temp
LDA byteB
AND #(the bits you want to keep)
ORA tempRe: how to write to individual bits of a byte
And in fact, the trick is one of the first things you come across when you disassemble the Monitor ROM of the Apple II.
Re: how to write to individual bits of a byte
I wonder if the terminator used that trick...
Re: how to write to individual bits of a byte
You'd have to look at Key Perfect, as that appears to be part of the hash table implementation used on the 6502-compatible microcontroller that runs Arnie's medium-term memory. In Key Perfect, each 50-byte record (or 80-byte? Sites are inconsistent on this) gets a 16-bit hash code.