'Include "CLib.bas"
' ****************************************************************************
' Functions to ensure compatibility with the C language.
' By COS, 2025/07/05, 2025/06, 2024/09, Pic18 OSHONSOFT V5.87
' ****************************************************************************
' Get_ToBin(), cShiftRight(), cShiftLeft(), cShift_Right(), Get_DecToBCD()
' Get_BcdToDec(), BitTest(), BitSet(), BitClear(), Abs(), AbsFloat()
' Get_LowNibble(), Get_HighNibble()
' ****************************************************************************

'UART1_Init 9600
'#define STRING_MAX_LENGTH = 32
'#define SINGLE_DECIMAL_PLACES = 2

' ----------------------------------------------------------------
' Function:    Get_ToBin
' Description: Returns a string composed of 1s and 0s that represents the number in binary.
' Arguments:   long_value (Long) - The value to represent in binary.
'              ndigit (Byte) - Number of digits to include in the result.
' Returns:     String consisting only of 1s and 0s; empty string if there is an error.
Function Get_ToBin[32](long_value As Long, ndigit As Byte) As String
    Symbol _Return = Get_ToBin          ' Alias to the function's return buffer (compiler specific)
    Dim idx As Byte                     ' Loop index for bit positions

    ' Validate requested digit count (must be between 1 and 32)
    If ndigit > 0 And ndigit <= 32 Then
        --ndigit                        ' Converts input to the range 0 to 31 digits.
    Else                                ' Invalid digit count?
        _Return = ""                    ' → Return empty string to signal error
        Exit                            ' → Leave the function early
    Endif

    ' Build the binary string from MSB down to LSB
    For idx = ndigit To 0 Step -1       ' Walk through each bit position
        If long_value.idx Then          ' Check if the current bit is set
            _Return(ndigit-idx) = "1"   ' → Store "1" in the output string
        Else                            ' Bit is clear
            _Return(ndigit-idx) = "0"   ' → Store "0" in the output string
        Endif
    Next idx

    _Return(ndigit-idx) = 0             ' Null terminate the string (C style)
End Function
'---------------------------------------------------------------
' C style helper functions for language compatibility.
'---------------------------------------------------------------
' Function:    cShiftRight
' Description: Shifts the bits of a byte to the right.
' Arguments:   byte_value (Byte ByRef) - The value to be shifted.
'              dp (Byte) - Number of positions to shift.
' Returns:     The shifted value of byte_value.
Function cShiftRight(ByRef byte_value As Byte, dp As Byte) As Byte
    byte_value = byte_value >> dp  ' Shift the value to the right.
    ReturnValue byte_value         ' Return the shifted value.
End Function
' Function:    cShiftLeft
' Description: Shifts the bits of a byte to the left.
' Arguments:   byte_value (Byte ByRef) - The value to be shifted.
'              dp (Byte) - Number of positions to shift.
' Returns:     The shifted value of byte_value.
Function cShiftLeft(ByRef byte_value As Byte, dp As Byte) As Byte
    byte_value = byte_value << dp  ' Shift the value to the left.
    ReturnValue byte_value         ' Return the shifted value.
End Function
'---------------------------------------------------------------
' Function:    cShift_Right
' Description: Shifts the bits of a byte to the right and updates the most significant bit.
' Arguments:   byte_value (Byte ByRef) - The value to be shifted.
'              dp (Byte) - Number of positions to shift.
'              state_Bit (Bit) - New value for the most significant bit.
' Returns:     The least significant bit shifted out.
'---------------------------------------------------------------
Function cShift_Right(ByRef byte_value As Byte, dp As Byte, state_Bit As Bit) As Bit
    ReturnValue byte_value.0       ' Return the least significant bit.
    byte_value = byte_value >> dp  ' Shift the value to the right.
    byte_value.7 = state_Bit       ' Update the most significant bit.
End Function
'---------------------------------------------------------------
' Function:    Get_DecToBCD
' Description: Decimal → packed BCD.
' Arguments:   dt (Long) - Decimal value to convert.
' Returns:     The value converted to BCD.
'---------------------------------------------------------------
Function Get_DecToBCD(dt As Long) As Long
    Symbol bcd = Get_DecToBCD
    Dim shift, digit As Byte
    bcd = 0
    shift = 0                          		' Current nibble shift
    While dt > 0
        digit = dt % 10                		' Decimal digit
        bcd = bcd | CLong digit << shift  	' Adds digit (nibble)
        dt /= 10                      		' Remove digit
        shift += 4                    		' 4 bits per nibble
    Wend
    ReturnValue bcd                   		' Return the converted BCD value
End Function
'---------------------------------------------------------------
' Function:    Get_BcdToDEC
' Description: Converts a packed BCD integer (up to 8 digits, 32 bits).
' Arguments:   bcd (Long) - BCD value to convert.
' Returns:     The value converted to decimal.
'---------------------------------------------------------------
Function Get_BcdToDec(bcd As Long) As Long
    Symbol decimal = Get_BcdToDec
    Dim multiplier As Long
    Dim digit As Byte
    decimal = 0
    multiplier = 1
    While (bcd)
        digit = bcd & 0xF             ' Extract the least‑significant nibble
        If digit > 9 Then Exit        ' (EXIT_FAILURE)
        decimal += digit * multiplier ' Accumulate
        multiplier *= 10              ' Next decimal place
        bcd = bcd >> 4                ' Next nibble
    Wend
    ReturnValue decimal
End Function
' *********************************************************************************
' Name: BitTest
' Description: Checks the status of a specific bit within a variable.
' Date: 2024/12/09
' Version: 1.0
' *********************************************************************************

Function BitTest(Var As Long, BitPos As Byte) As Bit
    ' Ensures the bit position is within the valid range (0‑31)
    If BitPos > 31 Then BitPos = 31
    ' Checks the specified bit state
    ReturnValue Var.BitPos
End Function

' *********************************************************************************
' Name: BitSet
' Description: Sets a specific bit to 1 within a variable.
' Date: 2024/12/09
' Version: 1.0
' *********************************************************************************

Function BitSet(ByRef Var As Long, BitPos As Byte) As Long
    ' Ensures the bit position is within the valid range (0‑31)
    If BitPos > 31 Then BitPos = 31
    ' Sets the specified bit using
    Var.BitPos = 1
    ReturnValue Var
End Function

' *********************************************************************************
' Name: BitClear
' Description: Clears a specific bit (sets it to 0) within a variable.
' Date: 2024/12/09
' Version: 1.0
' *********************************************************************************

Function BitClear(ByRef Var As Long, BitPos As Byte) As Long
    ' Ensures the bit position is within the valid range (0‑31)
    If BitPos > 31 Then BitPos = 31
    ' Clears the specified bit
    Var.BitPos = 0
    ReturnValue Var
End Function

' *********************************************************************************
' Name: ToBinary
' Description: Converts an integer to its binary string representation,
'              returned as a string with a user defined number of digits.
' Date: 2024/12/05
' Version: 1.0
' *********************************************************************************

'Function ToBinary[32](numBer As Long, ndigit As Byte) As String
    'Symbol _Return = ToBinary
    'Dim BitValue As Byte

    '' Clamp digit count between 1 and 32
    'If ndigit > 32 Then ndigit = 32
    'If ndigit = 0 Then ndigit = 1

    '' Initialize result string
    '_Return = ""
    'ndigit--

    '' Build binary representation from MSB to LSB
    'For BitValue = ndigit To 0 Step -1
        'If (numBer >> BitValue).0 Then
            '_Return = _Return + "1"   ' Append "1" if bit is set
        'Else
            '_Return = _Return + "0"   ' Append "0" if bit is clear
        'Endif
    'Next BitValue
'End Function

' *********************************************************************************
' Name: Abs
' Description: Calculates and returns the absolute value of a signed integer.
' Date: 2024/12/05
' Version: 1.0
' *********************************************************************************

Function Abs(numBer As LongInt) As LongInt
    ' Returns the positive value of the input
    If numBer < 0 Then
        ReturnValue -numBer
    Else
        ReturnValue numBer
    Endif
End Function

' *********************************************************************************
' Name: AbsFloat
' Description: Calculates and returns the absolute value of a floating‑point number.
' Date: 2024/12/05
' Version: 1.0
' *********************************************************************************

Function AbsFloat(numBer As Single) As Single
    ' Returns the positive value of the input
    If numBer < 0 Then
        ReturnValue -numBer
    Else
        ReturnValue numBer
    Endif
End Function

' *********************************************************************************
' Name: GetLowNibble
' Description: Returns the lower nibble (least significant 4 bits) of a byte.
' Date: 2024/12/05
' Version: 1.0
' *********************************************************************************

Function Get_LowNibble(ByteValue As Byte) As Byte
    ' Mask to extract the lower 4 bits
    ReturnValue ByteValue And 0x0F
End Function

' *********************************************************************************
' Name: GetHighNibble
' Description: Returns the upper nibble (most significant 4 bits) of a byte.
' Date: 2024/12/05
' Version: 1.0
' *********************************************************************************

Function Get_HighNibble(ByteValue As Byte) As Byte
    ' Shift upper 4 bits down to the lower 4‑bit position
    ReturnValue ByteValue >> 4
End Function
