Searching \ for 'Was {OT} [PIC] Basic Stamp application (Bitmask co' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: massmind.org/techref/microchip/languages.htm?key=basic
Search entire site for: 'Was {OT} [PIC] Basic Stamp application (Bitmask co'.

Truncated match.
PICList Thread
'Was {OT} [PIC] Basic Stamp application (Bitmask co'
2004\11\03@090037 by Bob Ammerman

picon face
>> On Mon, Oct 25, 2004 at 11:32:21AM -0400, Peter Johansson wrote:
{Quote hidden}

;---- untested code ----
;--  Assumptions:
;--        bit 0 is the LSBit
;--        0 <= start <= 7
;--        0 <= start + count <= 8

clear_port_b_bits:
   call        makemask
   xorlw    B'11111111'
   andwf    PORTB,F
   return

set_port_b_bits:
   call        makemask
   iorwf     PORTB,F
   return

toggle_port_b_bits:
   call       makemask
   xorwf    PORTB,F
   return

makemask:
   movf    start,w
   call       bit_to_mask
   movwf  temp

   movf     start,W
   addwf   count,W
   call        bit_to_mask
   xorlw    B'11111111'
   andwf    temp,W
   return

;--- assumption : following table doesn't span a 256
;--- instruction word boundary

bit_to_mask:
   addwf    PCL,f
   retlw      B'11111111'
   retlw      B'11111110'
   retlw      B'11111100'
   retlw      B'11111000'
   retlw      B'11110000'
   retlw      B'11100000'
   retlw      B'11000000'
   retlw      B'10000000'
   retlw      B'00000000'

Bob Ammerman
RAm Systems

____________________________________________

2004\11\03@091308 by Bob Ammerman

picon face
>> On Mon, Oct 25, 2004 at 11:32:21AM -0400, Peter Johansson wrote:
{Quote hidden}

;---- untested code ----
;--  Assumptions:
;--        bit 0 is the LSBit
;--        0 <= start <= 7
;--        0 <= start + count <= 8

clear_port_b_bits:
   call        makemask
   xorlw    B'11111111'
   andwf    PORTB,F
   return

set_port_b_bits:
   call        makemask
   iorwf     PORTB,F
   return

toggle_port_b_bits:
   call       makemask
   xorwf    PORTB,F
   return

makemask:
   movf    start,w
   call       bit_to_mask
   movwf  temp

   movf     start,W
   addwf   count,W
   call        bit_to_mask
   xorlw    B'11111111'
   andwf    temp,W
   return

;--- assumption : following table doesn't span a 256
;--- instruction word boundary

bit_to_mask:
   addwf    PCL,f
   retlw      B'11111111'
   retlw      B'11111110'
   retlw      B'11111100'
   retlw      B'11111000'
   retlw      B'11110000'
   retlw      B'11100000'
   retlw      B'11000000'
   retlw      B'10000000'
   retlw      B'00000000'

Bob Ammerman
RAm Systems

____________________________________________

2004\11\04@081326 by Byron A Jeff

face picon face
On Wed, Nov 03, 2004 at 08:56:24AM -0500, Bob Ammerman wrote:

Bob,

Thanks for pointing out the difference that I was trying to make. The high
level code is readable and compact. While PIC assembly, which is generally
always readable, represents a long path to the solution.

BAJ
{Quote hidden}

> ______________________________________________

2004\11\04@082345 by Byron A Jeff

face picon face
On Wed, Nov 03, 2004 at 08:56:24AM -0500, Bob Ammerman wrote:
{Quote hidden}

BTW Bob, here is the snippet of code I have for my NPCI bytecode interpreter
to handle the bitassign. NPCI's interpreter is stack based. So by the time
this routine is called, the interpreter will have already have put the variable
address, the bit number, and the value to be assigned onto the stack. This
routine pulls off all three values from off the stack, puts the address of the
target into FSR, then uses a jump table to do a bcf/bsf to the target bit.

I'm hoping to get one of my students to start cleaning up NPCI next semester
so that it can be released...

BAJ
;--------------------------------------------
; Changed this so that the bit number is picked up off the stack. It'll
; be beneath the value to be assigned. This will allow variable bit
; numbers for bit assign. Also now that bit assign for local/parameters
; need be done, this new method is better than having to pack a static
; bit number along with the variable. Be sure to mask off only 3 bits
; for the bit number.

bitassign                       ; Followed by variable address. Pop stack
                               ; and store in variable. Variable #'s from
                               ; 0 to 5 are virtual port numbers.

       call    gettoken        ; Get address of the variable
localbassign                    ; Entry point for bit assign to local var
       movwf   token           ; And save it
       sublw   specreg         ; See if special register
       btfss   STATUS,C        ; Not special. Continue on
       goto    bvarsetup
       call    assign_spec     ; Handle the specials differently
       goto    bsaveit
bvarsetup
       movf    token,W         ; Restore the register number
       addlw   varoff          ; offset to beginning of variables
bsaveit movwf   token           ; Save the address. This is complicated.

       incf    tos,F           ; POP stack
       movf    tos,W           ; Get the TOS
       movwf   FSR             ; Set up to get the bit number from the stack
       incf    tos,F           ; POP stack - removes both value and bit number
       movlw   .7              ; Mask so the bit number ranges from 0-7
       andwf   INDF,F
       bcf     STATUS,C        ; Setup for shift
       rlf     INDF,F          ; Double in prep for computed goto later

       decf    FSR,F           ; Setup to get the value
       movf    INDF,W          ; Get the value

       btfss   STATUS,Z        ; Zero - move on...
       movlw   .16             ; Move jump offset into W
       incf    FSR,F           ; Point to the bit number
       addwf   INDF,W          ; Finish up computed goto value
       movwf   command         ; And save for later
       movf    token,W         ; Get the variable address
       movwf   FSR             ; Put address in FSR to store value
       movf    command,W       ; Get the value
       addwf   PCL,F           ; Computed goto to change the correct bit

       bcf     INDF,0          ; Clear bit 0
       return                  ; All done.

       bcf     INDF,1          ; Clear bit 1
       return                  ; All done.

       bcf     INDF,2          ; Clear bit 2
       return                  ; All done.

       bcf     INDF,3          ; Clear bit 3
       return                  ; All done.

       bcf     INDF,4          ; Clear bit 4
       return                  ; All done.

       bcf     INDF,5          ; Clear bit 5
       return                  ; All done.

       bcf     INDF,6          ; Clear bit 6
       return                  ; All done.

       bcf     INDF,7          ; Clear bit 7
       return                  ; All done.

       bsf     INDF,0          ; Set bit 0
       return                  ; All done.

       bsf     INDF,1          ; Set bit 1
       return                  ; All done.

       bsf     INDF,2          ; Set bit 2
       return                  ; All done.

       bsf     INDF,3          ; Set bit 3
       return                  ; All done.

       bsf     INDF,4          ; Set bit 4
       return                  ; All done.

       bsf     INDF,5          ; Set bit 5
       return                  ; All done.

       bsf     INDF,6          ; Set bit 6
       return                  ; All done.

       bsf     INDF,7          ; Set bit 7
       return                  ; All done.

>
> Bob Ammerman
> RAm Systems
>
> ______________________________________________

2004\11\04@145904 by Andrew Warren

flavicon
face
Byron A Jeff <spam_OUTpiclistTakeThisOuTspammit.edu> wrote:

> proc clearbits(copy char count, copy char start)
>   while (count)
>      portb:start = 0 // Clear the bit in PORTB referenced by
>                      // start.
>      start = start+1
>      count = count-1
>   endwhile
> endproc
>
> The portb:start=0 line is a significant chunk of code because it
> represents a variable bit number. But the compiler gives a compact
> abstraction for the concept.

   Not disputing your point, but the existence of just one macro
   makes the assembly code even MORE compact than the high-level
   code:

       clearbits:
           CLRBIT  portb,start
           inc     start
           decfsz  count
           goto    clearbits

   Seems likely that most proficient PIC programmers would have a
   library of reusable macros and subroutines by now.

   -Andy

=== Andrew Warren -- .....aiwKILLspamspam@spam@cypress.com
=== Principal Design Engineer
=== Cypress Semiconductor Corporation
===
=== Opinions expressed above do not
=== necessarily represent those of
=== Cypress Semiconductor Corporation

____________________________________________

2004\11\04@174007 by Bob Ammerman

picon face
> Byron A Jeff <piclistspamKILLspammit.edu> wrote:
>
>> proc clearbits(copy char count, copy char start)
>>   while (count)
>>      portb:start = 0 // Clear the bit in PORTB referenced by
>>                      // start.
>>      start = start+1
>>      count = count-1
>>   endwhile
>> endproc
>>
>> The portb:start=0 line is a significant chunk of code because it
>> represents a variable bit number. But the compiler gives a compact
>> abstraction for the concept.

The point of the code that I sent regarding this is that sometimes brute
force is not the way to go. My trick of anding two masks together so that
all the bits can be zapped at once means that the code is probably faster
(except for very small values of 'count') and also probably shorter.

Perhaps if the same concept were expressed in "C" it would make more sense
to some....

const unsigned char mask_table[9] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0,
0xC0, 0x80,0x00 };

void clearbits(unsigned char start, unsigned char count)
{
   PORTB &= ~make_mask(start,count);
}

unsigned char make_mask(unsigned char start, unsigned char count)
{
   return mask_table[start] & ~mask_table[start+count];
}

Notice, no loops and pretty simple code. I would be tempted to turn
make_mask into a #define:

#define make_mask(start,count) (mask_table[(start)] &
~mask_table[(start)+(count)])

If you have a processor that can do multibit variable width shifts quickly
then you can create an even faster make_mask:

unsigned char make_mask(unsigned char start, unsigned char count)
{
   return (0xFF << start) &~ (0xFF << (start+count));
}

This could of course also be turned into a macro.


Bob Ammerman
RAm Systems

____________________________________________

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