6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 16, 2024 3:47 pm

All times are UTC




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: Controlling bits
PostPosted: Fri Jul 22, 2005 4:54 am 
Offline

Joined: Wed Jul 20, 2005 11:08 pm
Posts: 53
Location: Hawaii
I have an application in which individual bits in a byte need to be controlled. Can anyone show me how to set a bit in 6502 assembly language?

_________________
Sam

---
"OK, let's see, A0 on the 6502 goes to the ROM. Now where was that reset vector?"


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Jul 22, 2005 7:17 am 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
You can use AND or BIT to test the state of bits in a byte. for example:
Code:
LDA #$08
AND FLAGS
BNE Bit3IsSet
BEQ Bit3isClear

or

LDA #$08
BIT FLAGS
BNE Bit3IsSet
BEQ Bit3isClear

The BIT instruction is basically a non destructive AND. It also sets the N and V flags from bits 7 and 6 which can make tests on this bits quicker (e.g. no mask pattern required) but on a standard 6502 it only supports zero page and absolute addressing. AND is more versatile when it comes to addressing modes.

To set a bit use ORA with a suitable mask pattern
Code:
LDA #$08
ORA FLAGS
STA FLAGS

or

LDA FLAGS
ORA #$08
STA FLAGS

To clear a bit use AND with the complemented mask pattern
Code:
LDA #$F7
AND FLAGS
STA FLAGS

or

LDA FLAGS
AND #$F7
STA FLAGS

And to invert a bit use EOR
Code:
LDA #$08
EOR FLAGS
STA FLAGS

or

LDA FLAGS
EOR #$08
STA FLAGS

You can combine several action on several bits simultaneously
Code:
LDA FLAGS
ORA #$03 ;Set bits 0 & 1
AND #$3F ;Clear bits 7 & 6
EOR #$18 ;Invert bits 4 & 3
STA FLAGS

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Jul 22, 2005 9:18 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8541
Location: Southern California
Don't forget that if you can use the 65c02, you also have TSB (test and set bit) and TRB (test and reset bit). If you already have the mask in the accumulator, the read-test-modify-write process to memory takes only one instruction. The addressing modes available for these are absolute and zero page-- no indirects or indexeds (if I can make that a word).

If you have Rockwell's or WDC's 65c02, you further have the BBS (branch on bit set), BBR (branch on bit reset), SMB (set memory bit), and RMB (reset memory bit) available for zero page.

The first two, BBS and BBR, are 3-byte instructions. The first byte (the op code) actually also tells which bit to test (meaning you don't ever need a mask in the accumulator). The second byte tells which address in zero page to test. The third byte tells how far in which direction to branch if appropriate (meaning you don't have to follow it with a conditional branch instruction). It's all wrapped up in a single instruction.

The other two, SMB and RMB, are 2-byte instructions. The first byte (the op code) actually also tells which bit to set or clear (again meaning you don't ever need a mask in the accumulator). The second byte tells which address in zero page to modify.

As BitWise mentioned, simply using the BIT instruction (regardless of what's in the accumulator, and without affecting it) will set or clear the N flag according to bit 7 of the contents of the address you test, and set or clear the V flag according to bit 6 of the contents of the address you test. This gives special convenience if you connect individual I/O bits you want to test to bits 7 and 6 of I/O ICs like the 6522. You can use the BIT instruction immediately followed by a conditional-branch instruction, with no need to affect the accumulator or use AND or ORA.

Another convenience for output is to put a bit you want to toggle on bit 0 of an I/O IC. As long as the program keeps track of the state of that bit, you can turn it on or off with a single instruction by using INC or DEC on the port. If it's 0 and you want to change it to 1, you don't need to load the port, ORA #1, and store it back-- just INC it. A single instruction takes care of it. The other bits (and the accumulator) will be unaffected. If it's a 1 and you want to make it a 0, just DEC it.

You can use the same trick if you want to have two output bits toggle opposite each other, going from 01 to 10 (in binary) and vice-versa. INC takes 01 to 10, and DEC takes 10 to 01. No need to LDA addr, ORA#, AND#, STA addr, or even LDA addr, EOR#, STA. Just one instruction, INC or DEC on the I/O port where you have the two out-of-phase lines connected on port bits 0 and 1, will do the job.

The 6522 has special functions available for PB7 and PB6. PB7 can be made to toggle automatically every time T1 rolls over, and PB6 can be used as an external clock to trigger T2's counting. Simple application examples would include using PB7 to produce annunciator beeps while the processor is doing something else (so the processor doesn't have to stop everything it's doing just to babysit the port that's putting out a square wave), and using the PB6 input as a frequency or event counter that only interrupts the processor when it gets to a count that you've selected. Note that putting out a tone on PB7 as mentioned here, the tone will not be affected by interrupts.

You should download WDC's programming manual from the lower-right area of their front page at www.westerndesigncenter.com . I think it's the best there is.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: