Global or Shared String variable used as parameter in procedures?

Started by trastikata, Jun 22, 2024, 09:33 AM

Previous topic - Next topic

trastikata

Hello,

is it possible to use a Global or Shared string variable sMyString as parameter for procedure? I've tried passing the string parameter using ByRef but it is not accepted.

I have different procedures creating and/or manipulating strings and those strings are being passed between procedures as parameters, however that string is never being used by two or more procedures in its original state.

That means I can use the same RAM space as string source (parameter) or destination (result) by all procedures. Any ideas how to achieve that?

keytapper

I think you may use a pointer of the string. Then you may use ptr8(address++) to access one byte at time with post-increment.
I have some idea to use indirect pointing FSR, but I'm not aware to use 18F family.

I have done something like this
Device = 18F25K22
Xtal = 6432

Declare Hserial_Baud 9600
$define CONVERSION
Dim RXBUFSIZE As 64
Dim STRSIZE As 32
Dim rxbuffer[RXBUFSIZE] As Byte Heap
Dim readbuf As String * STRSIZE  Heap
Dim position As Byte
rxbuffer = "this is a long story"
readbuf = "Hello, a new story less wordy"

HSerOutLn ["ready"]
position = parseBuffer(0, rxbuffer, "STORY")
HSerOutLn ["Match end in rxbuffer at ", Dec position]
position = parseBuffer(0, readbuf, "STORY")
HSerOutLn ["Match end in readbuf at ", Dec position]

Proc parseBuffer(bufidx As Byte, ByRef ramPos, ByRef cmpPhrase),Byte
  Dim chk_chr As Byte               ' initial state avoiding exit immediately
  Dim chk_idx As Byte = bufidx      ' memorize the initial value
  Inc chk_idx                       ' minimum exit value
  Dim bufchr As Byte                ' local variable to store the read in RAM
  ' memorize the initial sequence start
  Dim oldcmpPhrase As Word = cmpPhrase
  Dim startcmp As Bit               ' signal that the sequence has started
  Inc ramPos,bufidx                 ' set to the desired point in RAM
  Do
    bufchr = Ptr8(ramPos++)         ' read the RAM value and increase for next
    Skpnz                           ' is it a zero?
    Break                           ' leave the loop
'===================== just a particulare option ============================
$ifdef CONVERSION
    If bufchr = 32 Then             ' if space
      Inc bufidx                    ' ignore it
      Continue                      ' one more character
    End If
    ' only for alpha characters, convert then to upper case
    If bufchr > 95 And bufchr < 127 Then
      bufchr = bufchr & 95
    End If
$endif
'===================== just a particulare option ============================
    chk_chr = CRead cmpPhrase         ' read the flash value
    Skpnz
    Break                             ' Break if it's a zero
    Inc bufidx                        ' increse the position in the RAM
    If bufidx > STRSIZE Then Break    ' in case is going over the limits
    If bufchr = chk_chr Then          ' when they are same
      Set startcmp                    ' signalize the start of the matching
      Inc cmpPhrase                   ' look for the next
    Else                              ' otherwise, when different
      If startcmp = 1 Then            ' if already started to compare
        oldcmpPhrase = cmpPhrase      ' reset the pointer and try again
        Clear startcmp                ' new start condition
      End If
      Continue                        ' go futher in tne RAM
    End If
  Loop
  ' anything has been found, it returns a value next to the matching end
  If bufidx > chk_idx Then            ' changed?
    Result = bufidx                   ' found a value after the match
  Else
    Clear Result                      ' no one matched, return zero
  End If
EndProc
I hope you can have some benefit.
Ignorance comes with a cost

trastikata

Thank you keytapper.

What you suggest is different from what I am looking for.

Just for demonstration this simplified code requires 143 bytes of RAM while in reality, if you follow the logic, it can be done with 33 bytes of RAM only if the same RAM space as sMyString is used because it will never interfere with procedures. 

So instead of "sMyString = BuildMyString()" I would call only BuildMyString() and its result can be stored at the same RAM as sMyString. Then instead of ModifyMyStringThisWay(sString As String * 32, bParameter1 As Byte) having another 33 bytes of RAM for sString, it can directly use sMyString as parameter input because the string is already there etc.


Dim sMyString As String * 32

Main:
    sMyString = BuildMyString()
    PrintMyString(sMyString)
End

Proc BuildMyString(), String * 32
    Result = "Test test test"
EndProc

Proc ModifyMyStringThisWay(sString As String * 32, bParameter1 As Byte)
    'Do something with sString according parameter1
EndProc

Proc PrintMyString(sString As String * 32)
    ModifyMyStringThisWay(sString, 10)
    'Print  
EndProc

atomix

Device 18F46K22
Declare Xtal 64

Dim sMyString As String * 32

Main:
    BuildMyString()
    PrintMyString(sMyString)
End

Proc BuildMyString(), sMyString
    Result = "Test test test"
EndProc

Proc ModifyMyStringThisWay(sString As sMyString, bParameter1 As Byte)
    'Do something with sString according parameter1
EndProc

Proc PrintMyString(sString As sMyString)
    ModifyMyStringThisWay(sString, 10)
    'Print 
EndProc

JonW

I looked back at my digital screen code, I had to use the sSTRING as STRING * 32, same as you have done. 

In the end, I sent the start point, number of chars, string and colour to the procedure.

PRINTAT (1,10,"FULL  TIME",blue) ' Procedure call

PROC PRINTAT(WS_LOC AS BYTE, NUM_CHAR AS BYTE,MYSTRING AS STRING * 20,COL AS BYTE)
' do stuff
ENDPROC

It will be interesting to see if that works ok, Atomix. 

trastikata