Don_Kirby wrote:I can't get a working method to pass the information along to another function or sub that can be called from multiple locations.
There is no easy solution to this problem but it can be solved if you don't mind using some implementation-specific information. Firstly, consider this program fragment that has two string tables and a call to a single routine to display a particular string from each one of them. Here, the address of the string table is passed to the display routine.
Code: Select all
Dim ps1 as StringVectorData({
"able",
"baker",
"charlie",
"delta"
})
Dim ps2 as StringVectorData({
"red",
"orange",
"yellow",
"green"
})
Sub Main()
Call dspStr(CUInt(ps1.DataAddress), 3)
Call dspStr(CUInt(ps2.DataAddress), 2)
End Sub
There a several ways that the display routine could be implemented but they rely on information about how the StringVectorData structure is implemented. If you look at a listing file, you'll see that two pieces of information are generated for StringVectorData: an index table and the string data. The each entry of the index table contains the Program Memory address where the corresponding string begins. The actual string data consists of a byte giving the string length, a zero byte, then the characters of the string. This latter content happens to be the same format as used by the BoundedString type, which fact is exploited in the of second solution.
First, the brute force" solution.
Code: Select all
Sub dspStr(ByVal strTbl as UnsignedInteger, ByVal idx as Integer)
Dim addr as UnsignedInteger
Dim strData as ProgMem Byte Based addr
Dim strLen as Byte
' read the string address from the index table
Call GetProgMem(CLng(strTbl + CUInt(idx - 1) * 2), addr, 2)
' read the string's length and advance the address to the first character
strLen = strData
addr = addr + 2
' display the characters of the string
Do While (strLen > 0)
Debug.Print Chr(strData);
addr = addr + 1
strLen = strLen - 1
Loop
Debug.Print
End Sub
The second solution is perhaps a bit more elegant but uses more stack space.
Code: Select all
Sub dspStr2(ByVal strTbl as UnsignedInteger, ByVal idx as Integer)
Const MaxStrLen as Byte = 30
Dim addr as UnsignedInteger
Dim strLen as Byte
Dim str as BoundedString(MaxStrLen)
' read the string address from the string table
Call GetProgMem(CLng(strTbl + CUInt(idx - 1) * 2), addr, 2)
' read the string length
Call GetProgMem(CLng(addr), strLen, 1)
' limit the string length to fit in the string variable
If (strLen > MaxStrLen) Then
strLen = MaxStrLen
End If
' populate the string variable
Call GetProgMem(CLng(addr), str.DataAddress, strLen + 2)
' set the string length (possibly truncated)
Call RamPoke(strLen, str.DataAddress)
Debug.Print str
End Sub
The code for both implementations does not validate the index but it should. A third parameter could be supplied giving the highest valid index. The lowest valid index is 1.
It should be noted that SizeOf(ps1) returns the value 8, i.e. it returns the size of the index table, twice the number of entries in the table.