Searching \ for '[PIC]: asm question' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/languages.htm?key=asm
Search entire site for: 'asm question'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: asm question'
2000\06\26@061642 by Russell Farnhill

flavicon
face
Hi all,

I have just started learning asm and playing around with a 16f84. I've
already read
a couple of tutorials from the net and now have a question. How do I create
a function
that uses a bit orientated command and pass its arguments via a register. I
have
included a small piece of code to try and illustrate.

#include        "p16f84.inc"
#DEFINE PAGE0 bcf STATUS,5
#DEFINE PAGE1 bsf STATUS,5

RBpin equ 0x0C          ; Port B pin number


       org 4
       goto start

start
       clrf    PORTB           ; clear portb
       PAGE1                   ; select bank 1
       clrf    PORTB           ; portb all output's
       PAGE0                   ; select bank 0

loop    movlw   0               ; bit 0 portb
       movwf   RBpin           ; move bit select into register
       call    foobar  ; test function
       goto loop

foobar

       bsf     PORTB,RBpin
       return

       END

When I compile this I get the error "Argument out of range.  Least
significant bits used".
I guess this is because bsf expects a single bit arg but I pass it a byte. I
tried loading
W with my bit number and then read W from within my function which worked
fine, but if I
need to pass 2 args I can't use W as one arg overwrites the other.

Any suggestions ?

Thanks Russell.

2000\06\26@063133 by H.P. de Vries

flavicon
face
See remars between code
On Mon, Jun 26, 2000 at 11:17:16AM +0100, Russell Farnhill wrote:
{Quote hidden}

What you are doing here is effectively a
       bsf   PORTB,0x0C
So it indeed can't work.

{Quote hidden}

What I would do is something like :

       RBpin   EQU     0x0C
                               ;bit to set is in RBpin,
                               ; eg. b'00001000'
foobar
       COMF    RBpin,w         ; set b'11110111' in w , complement of RBpin
       ANDWF   PORTB,w         ; make sure bit to set is 0, store in w
       XORWF   RBpin,w         ; make that bit '1' now, store in w
       MOVWF   PORTB           ; set ouput port
return

I hope I got this correct.

There may be a faster (smaller) solution, but can't think of any.

Hans

2000\06\26@090614 by Bob Ammerman

picon face
The bit manipulation insturctions (BTFxx, BSF and BCF) all include the bit
number as an immediate value within the instruction. You cannot pass a bit
number to these instructions in  a register.

However, you can get the same effect by using a bit _mask_ rather than a bit
_number_ and using the ANDWF or IORWF instructions. You can convert a bit
number to a bit mask using a short table lookup function.

Bob Ammerman
RAm Systems
(high performance, high function, low-level software)

{Original Message removed}

2000\06\26@105946 by Russell Farnhill

flavicon
face
So basically what I was doing was passing the address of
the register rather than its contents ?

I could write this so much easier in C but I'am
determined to get to grips with asm.

Ok thanks guys, I'll keep at it.

Russ.

> {Original Message removed}

2000\06\26@175803 by Bob Ammerman
picon face
Perhaps a good way to understand this is to look at the actual bit pattern
of a BSF instruction:

This example is for the 16C84:

The instruction is 14 bits long, as follows:

0 1 0 0 B B B F F F F F F F

where "0 1 0 0" is the opcode that identifies this as a BSF instruction,

"B B B" is a 3-bit binary number in the range of 0 to 7 that identifies the
bit to be set,

and "F F F F F F F" is a 7-bit binary number in the range of 0 to 127 (ie
0x7F) that defines the file register to be affected.

You will notice that there is no way to indicate in this format that the bit
number should be obtained from the W register, or a file register, or any
other such location.

Here is some code that could be helpful (all based on the 16C84). (Note that
this code assumes that 'read-modify-write' instructions to ports will work
OK in your application. See notes in the Microchip datasheets about BSF and
BCF on ports if you don't understand what I mean by this).

CBLOCK xxx
   bitno        ; register containing bit to set/reset
ENDC

; To turn on bit 'bitno' on PORTB (leaves rest of PORTB alone)

   movf    bitno,W
   call      BitToMask
   iorwf   PORTB,F

; To turn off bit 'bitno' on PORTB (leaves rest of PORTB alone)

   movf    bitno,W
   call      BitToMask
   xorlw   0xFF                ; Complement all the bits
   andwf  PORTB,F

; To see if bit 'bitno' is set on PORTB

   movf    bitno,W
   call      BitToMask
   andwf  PORTB,W
   btfss    STATUS,Z
   goto     bit_was_set
   goto     bit_was_clear

; A subroutine to convert from a bit number to the corresponding bit mask:
;
;    On entry: WREG is a bit number in the range 0..7
;    On exit:   WREG is the mask for the corresponding bit

BitToMask:
   addwf        PCL,F
   retlw  0x01
   retlw  0x02
   retlw  0x04
   retlw  0x08
   retlw  0x10
   retlw  0x20
   retlw  0x40
   retlw  0x80

----- Original Message -----
From: Russell Farnhill <spam_OUTr.farnhillTakeThisOuTspamSTOR-WAVE.CO.UK>
To: <.....PICLISTKILLspamspam@spam@MITVMA.MIT.EDU>
Sent: Monday, June 26, 2000 11:01 AM
Subject: Re: [PIC]: asm question


> So basically what I was doing was passing the address of
> the register rather than its contents ?
>
> I could write this so much easier in C but I'am
> determined to get to grips with asm.
>
> Ok thanks guys, I'll keep at it.
>
> Russ.
>
> > {Original Message removed}

More... (looser matching)
- Last day of these posts
- In 2000 , 2001 only
- Today
- New search...