Page 1 of 1

TestBit, SetBit, ClearBit, MemCpy, MemCmp

Posted: Thu Sep 27, 2007 12:42 pm
by yo2lio
I don't know if exist .... So I wrote few functions ....

Code: Select all

{
****************************************************************
*  Name    : Util.BAS                                          *
*  Author  : Medrea Florin Andrei                              *
*  Notice  : Copyright (c) 2007 -YO2LIO-                       *
*          : All Rights Reserved                               *
*  Date    : 9/27/2007                                         *
*  Version : 1.0                                               *
*  Notes   :                                                   *
*          :                                                   *
****************************************************************
}

Module Util

Public Sub ClearBit(ByRef data As Byte, pos As Byte)
Dim Pin_,PinMask_ As Byte 
    FSR2 = AddressOf(data)
    Pin_ = 1 << pos
    PinMask_ = Not(Pin_) 
    INDF2 = INDF2 And PinMask_
End Sub

Public Sub SetBit(ByRef data As Byte, pos As Byte)
Dim Pin_ As Byte 
    FSR2 = AddressOf(data)
    Pin_ = 1 << pos
    INDF2 = INDF2 Or Pin_
End Sub

Public Function TestBit(ByRef data As Byte, pos As Byte) As Byte
Dim Pin_ As Byte 
    FSR2 = AddressOf(data)
    Pin_ = 1 << pos
    If (INDF2 And Pin_) > 0 Then result = 1
    Else result = 0 End If
End Function

Public Sub MemCpy(addr1, addr2, len As Word)
Dim i As Word
    FSR1 = addr1
    FSR2 = addr2
    i = 0
    While i < len
        POSTINC1 = POSTINC2
        Inc(i)
    Wend
End Sub

Public Function MemCmp(addr1, addr2, len As Word) As Byte
Dim i As Word
    FSR1 = addr1
    FSR2 = addr2
    i = 0
    result = $FF
    While i < len 
        If POSTINC1 <> POSTINC2 Then Exit End If
        Inc(i)
    Wend
    result = 0
End Function
Examples :

ClearBit(PORTC,5)
// Clear bit 5 from PORTC

SetBit(PORTC,5) // Set bit 5 from PORTC

res = TestBit(PORTC,5)
// Test bit 5 from PORTC, return 0 or 1

MemCpy(@data1, @data2, 100) // Copies 100 bytes from the memory area starting at the address data2 to data1.

res = MemCmp(@data1, @data2, 100)
// Compare 2 parts from memory area starting at the address data2 and data1, return 0 if it's the same, else 255.

Posted: Thu Sep 27, 2007 12:52 pm
by octal
hi Yo2lio, thank you for your code.

I think that SetBit and ClearBit are usefullness, since for any variable (using modifiers) we can access each bit/byte or whatever part easily

Code: Select all

dim Value as word
Value.Byte1 = $FF

dim Value as byte
Value.0 = 1  // set
Value.5 = 1  // Clear

and Using Aliased with modifier you can get more power. Read the help file and the PDF documentation of Swordfish (Language Reference::Alias and Modifers section).

btw. writing to ports is better done using Latch register instead of Port regesiter (to avoid the read/write pic ports' mechanism/problem).

For memcopy function, you should also look at the string.bas library module. you'll find there some byte moving functions (this is the main advantage to have libs with open source codes... thanks David) ;)


Regards
octal

Posted: Thu Sep 27, 2007 1:41 pm
by yo2lio
Hi Octal,

I agree with you.

But, how can I handle this situation (without using INDIRECT ADDRESING) : Bit is variable in program ...

Code: Select all

Dim array1(100) As Byte
Dim j,var_bit As Byte

TRISB = $07
j = 0
While j < 100
    var_bit = PORTB And $07 // bit is variable input 
    SetBit(array1(j),var_bit)
    Inc(j)
Wend    
BTW, my memcpy routine copy more than 256 bytes !!!

Posted: Thu Sep 27, 2007 2:25 pm
by octal
yes in this case Indirect Addressing is mandatory. This technique is used in some modules where we pass the port pin as param to functions like in SUsart module.

Regards
octal

Posted: Thu Sep 27, 2007 2:46 pm
by David Barker
There are a few ways of handling PORTS with Swordfish

Direct Addressing

Code: Select all

output(PORTD.7)
PORTD.7 = 1  ' set high
PORTD.7 = 0  ' set low
Indirect Addressing (1)

Code: Select all

dim Index as byte
PORTD = 0
TRISD = 0
for index = 0 to 7 
   PORTD.Bits(index) = 1
   delayms(500)
next   
Indirect Addressing (2)

Code: Select all

Sub Set(ByRef pPin As Bit)
   Dim Mask As Byte
   Mask = BitOf(pPin)

   FSR0 = @pPin
   INDF0 = INDF0 Or Mask
   Mask = Not Mask
   Inc(FSR0, 18)
   INDF0 = INDF0 And Mask
End Sub   
Set(PORTD.3)
Indirect Addressing (3)

Code: Select all

Sub Set(ByRef pPin As Bit)
   high(pPin)
End Sub   
Set(PORTD.3)
The next Swordfish update has more optimised code generation for example (3) above - at the moment is is less than ideal.

Swordfish will always read from PORT, write to LATCH. That is,

Code: Select all

PORTD.0 = 1
will generate

Code: Select all

BSF LATD,0

Posted: Thu Sep 27, 2007 2:52 pm
by yo2lio
Thanks