TestBit, SetBit, ClearBit, MemCpy, MemCmp

Coding and general discussion relating to user created compiler modules

Moderators: David Barker, Jerry Messina

Post Reply
yo2lio
Posts: 39
Joined: Tue Sep 25, 2007 6:52 pm
Location: Arad, Romania
Contact:

TestBit, SetBit, ClearBit, MemCpy, MemCmp

Post by yo2lio » Thu Sep 27, 2007 12:42 pm

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.
Best regards, Florin Medrea
My UserLibrary Folder http://www.microelemente.ro/Swordfish/UserLibrary/

User avatar
octal
Registered User
Registered User
Posts: 584
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Post by octal » Thu Sep 27, 2007 12:52 pm

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

yo2lio
Posts: 39
Joined: Tue Sep 25, 2007 6:52 pm
Location: Arad, Romania
Contact:

Post by yo2lio » Thu Sep 27, 2007 1:41 pm

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 !!!
Best regards, Florin Medrea
My UserLibrary Folder http://www.microelemente.ro/Swordfish/UserLibrary/

User avatar
octal
Registered User
Registered User
Posts: 584
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Post by octal » Thu Sep 27, 2007 2:25 pm

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

User avatar
David Barker
Swordfish Developer
Posts: 1194
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Post by David Barker » Thu Sep 27, 2007 2:46 pm

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

yo2lio
Posts: 39
Joined: Tue Sep 25, 2007 6:52 pm
Location: Arad, Romania
Contact:

Post by yo2lio » Thu Sep 27, 2007 2:52 pm

Thanks
Best regards, Florin Medrea
My UserLibrary Folder http://www.microelemente.ro/Swordfish/UserLibrary/

Post Reply