I would like to use a subroutine like the GLCDPRINT command, just renaming it into GLCDtinyPRINT using my own code to write on screen. This way it would be easy to switch back and forth, when testing and sending simple fixed messages to the screen.
GLCDtinyPRINT (5, 5, "H" as string)
Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText)
... ...
This works, but is limited to one letter, otherwise I get:
TinyStringtoGLCDinasub.gcb (76): Error: Duplicate, conflicting definition for DISPLAYTEXT
This works for multiple letters, but is not as convenient:
DIM sometext as String
sometext = "HELLO"
GLCDtinyPRINT (5, 5, sometext)
Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText)
... ...
Is there another way, suggestion or should I just accept and go on?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Roger - I am not sure what the issue is. Some simpl/example code would help.
But, this works.
#CHIP 16f886
#option Explicit
GLCDtinyPRINT (5, 5, "H")
End
Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText )
// Do something
End Sub
But, is the real question... 'how do I write my own GLCD routines while using all the GLCD functions ? As there is no point of writing the same string handlers. Just need what to change to interrupt the write processes.
Answer: Take a copy of the GLCD routine 'GLCDDrawChar' that is used for your specific GLCD.
So, adding the following will redirect the routine to your solution. So, you can take the code from your GLCD specific GLCDDrawChar, add your changes then call PSET to set the pixel.
'''Draws a character at the specified location on the GLCD '''@paramStringLocXXcoordinateformessage'''@param CharLocY Y coordinate for message '''@paramCharsStringtodisplay'''@paramLineColourLineColor,either1or0SubGLCDDrawChar(InCharLocXasword,InCharLocYasword,InCharCode,OptionalInLineColourasword=GLCDForeground)//DostuffthencallPSET()EndSub
Much easier.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am trying to use my code TinyStringtoGLCD that I wrote couple of months ago (you helped touching it up and posted it as a demo) and use it in another program. I need to talk to it in some way, so I used a sub to pass the parameters to it and to start it off. The problem I have is passing more than one letter through the sub in the oneliner below.
The oneliner is more convenient in use than the workaround, especially when modifying code that alread has GLCDPRINT in it.
No big deal other than that I got stuck wondering why I can only pass one letter.
// Single letter works
GLCDtinyPRINT (5, 5, "H")
// This generates an error Error: Duplicate, conflicting definition for DISPLAYTEXT
GLCDtinyPRINT (5, 5, "HELLO")
//This workaround works:
DIM sometext as String
sometext = "HELLO"
GLCDtinyPRINT (5, 5, sometext)
(The gcb file is attached)
Thank you. I undertand, And I thank you for the program.
The error is actually correct. The error caused by the definition of the variable in the sub Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText ). The displayText as shown above will be defined as a byte. The default variable type is a byte. This is should be a string.
* A byte can handle a string like "H". "H" is treated as a byte when passed to the sub.
* GLCDtinyPRINT (5, 5, sometext) works as sometext equates to an array. ( Strings in a variable are just Arrays ). So, each element is passed to the Sub as a byte.
So, "HELLO" fails as this string constant. The way to resolve. Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText as String ) You can reduce the memory used by constraining the string Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText as String * 8 ) . The * 8 constrains to 8 bytes + 1 handler byte 9 bytes.
So, the compiling will try to compile but will fail when you try a string constant.
This will fail. And this is correct.
GLCDtinyPRINT (5, 5, "HELLO")
Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText )
This will work. And this is correct.
GLCDtinyPRINT (5, 5, "HELLO")
Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText as String * 5 )
I hope this explains.
👍
1
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
So, the compiler needs to know the number of letters to reserve, when sending it into the sub "directly" with the "oneliner" (no automatic buffer generated in this case). Good. Now I know.
Thank you for the explanation.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The standard size of RAM to use for the string is "40 bytes for devices with more RAM than 367 bytes"? -Unless the string is in the subroutine call, then the standard size is one byte. Right?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
“Yes, and each character in a string is one byte?”
Yes, each character in a string occupies one byte, plus one additional byte for internal management. Formula: Number_of_bytes_allocated = 1 + (length of string)
🧠 RAM Usage Guidelines for Strings
“The standard size of RAM to use for the string is ‘40 bytes for devices with more RAM than 367 bytes’? Unless the string is in the subroutine call, then the standard size is one byte. Right?”
The standard RAM allocation for a string is 40 bytes, but only on devices with more than 367 bytes of RAM.
You can override the default size using the * size construct.
Example:
Dim myString As String * 8
This creates a string of 8 characters, using 9 bytes of RAM (8 for content plus 1 for overhead).
You can pass a single character from a string to a subroutine or function using a Byte variable.
As the ASCII value of the character (range: 0 to 255) is passed this is supported.
To pass a string type variable to a subroutine or function, you must use the correct type declaration (String) in the subroutine or function definition.
The string variable in the subroutine can be constrained to limit RAM usage.
Ensure the constrained string is large enough to accommodate the longest string that may be passed.
👍
1
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Attached is an update to improve the handling of this type of error.
Apply the update module by double clicking it will install the patch files. You will need the latest build of GC Studio. This MKV contains all the new files and you can remove safely using the module manager within GC Studio.
I updated before seeing the video. I was a little confused by the "remove selected" but I took a chance, just went ahead and it just worked! How great is that! Now there is a understandable "problems" message generated when I try to run the code that I asked about. It used to say that there were no problems and I had to select and scroll "terminal" to find out about the problem, then not exactly understanding what it meant. The reason for this thread.
Thank you for the video explaining things, as well as the attention! :)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
So I inserted my my code TinyStringtoGLCD PongyThingy Game and weird things happened.
I changed from GLCDPRINT (which worked fine) to GLCDtinyPRINT which used my TinyStringtoGLCD drawing routine. As long as I only used it to print the ScoreR and ScoreL strings I could get it to work, but If I inserted the code line for "GAME OVER", then the screen would neither print ScoreR nor ScroreL, DESPITE that the condition for "GAME OVER" had not yet occured!
Then at gameover condition I could sometimes get it to print "game over", but after that the screen got corrupted, the text ending up in the wrong place and next time I tried to print anything a bunch of distortions. I had to cut the power to the circuit and restart it.
I tried fiddling with the displayText as string x10 and even at x40 it would not work ("game over" is the longest string). Then at last I tried using only "displayText as string" (not ...string*10) and it started working. Huh??? Does this * size construct need resetting? Or what may be the cause?
sub scoreprint
GLCDtinyPRINT (44, 10, Bytetostring(ScoreR))
GLCDtinyPRINT (15, 10, Bytetostring(ScoreL))
If ScoreR = 11 or ScoreL = 11 Then
GLCDtinyPRINT (10, 20,"GAME OVER") //= problems when using size construct *10
wait 5 s
startgame 'start new game
end if
end sub
Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText as string10)
//removing the 10 makes it work. 30 or40 didn't work either
Then it still prints "GAME OVER" and further 8 bytes are saved.
Seems to me that it is passing the string/bytes one by one(?), or what may be happening?
From 429 bytes, to 399, to 391
and 38 bytes saved.
Last edit: Roger Jönsson 5 days ago
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am going to ask Hugh to explain what is going on here. But, we have a method.... define the string in the sub and I would set to the correct string size. It is not passing one character - this asm shows this.
Be back on this... later. Hugh can take a long time to respond.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Right, the whole string seems to be passed (why didn't I test this yesterday...) Len(displayText) is 9 bytes with "GAME OVER" for all below cases.
TinyStringtoGLCDinasub.html reports:
...
Chip resource usage:
Chip Model: 16F15376
...
Dim displayText as string * 1 :
Program Memory: 921/16384 words (5.62%)
RAM: 340/2048 bytes (16.6%)
Dim displayText as string * 10 :
Program Memory: 921/16384 words (5.62%)
RAM: 348/2048 bytes (16.99%)
Dim displayText as string :
Program Memory: 921/16384 words (5.62%)
RAM: 378/2048 bytes (18.46%)
...
If I print only "game" (with Dim displayText as string * 1 ) then RAM use drops further
RAM: 335/2048 bytes (16.36%)
The same if I print "GAME" and then "OVER" -still 335 bytes.
"GAME" and then "OVER2" = 336 bytes.
So the extra RAM consumed with -Dim displayText as string x whatever - seems not being used and the string is in some other special place that is proportional to the largest string size in the code.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Feeding this to the sub, total use of RAM in my program is 371bytes:
Dim mystring as String
mystring = "GAME"
GLCDtinyPRINT (5 , 5 , mystring)
Replacing with this = 335 bytes:
GLCDtinyPRINT (5, 5, "GAME")
In both cases the * x in the Dim displayText as string * x does not seem to affect the result, only increasing RAM use. It does not work a constraint either.
However, putting the constraint/limitation - displayText as string * 2 - in the subroutine line, does limit and fix RAM to max 2 letters and only "GA" prints. But only has an effect for the string that is created outside the subroutine call:
Dim mystring as String
mystring = "GAME"
GLCDtinyPRINT (5,5,mystring) //This prints "GA"
//GLCDtinyPRINT (5, 10, "GAME") // This would print "GAME"
Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText as string * 2)Dim displayText as string * 1
Last edit: Roger Jönsson 3 days ago
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I would like to use a subroutine like the GLCDPRINT command, just renaming it into GLCDtinyPRINT using my own code to write on screen. This way it would be easy to switch back and forth, when testing and sending simple fixed messages to the screen.
GLCDtinyPRINT (5, 5, "H" as string)
Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText)
... ...
This works, but is limited to one letter, otherwise I get:
TinyStringtoGLCDinasub.gcb (76): Error: Duplicate, conflicting definition for DISPLAYTEXT
This works for multiple letters, but is not as convenient:
DIM sometext as String
sometext = "HELLO"
GLCDtinyPRINT (5, 5, sometext)
Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText)
... ...
Is there another way, suggestion or should I just accept and go on?
Roger - I am not sure what the issue is. Some simpl/example code would help.
But, this works.
But, is the real question... 'how do I write my own GLCD routines while using all the GLCD functions ? As there is no point of writing the same string handlers. Just need what to change to interrupt the write processes.
Answer: Take a copy of the GLCD routine 'GLCDDrawChar' that is used for your specific GLCD.
So, adding the following will redirect the routine to your solution. So, you can take the code from your GLCD specific GLCDDrawChar, add your changes then call PSET to set the pixel.
Much easier.
I am trying to use my code TinyStringtoGLCD that I wrote couple of months ago (you helped touching it up and posted it as a demo) and use it in another program. I need to talk to it in some way, so I used a sub to pass the parameters to it and to start it off. The problem I have is passing more than one letter through the sub in the oneliner below.
The oneliner is more convenient in use than the workaround, especially when modifying code that alread has GLCDPRINT in it.
No big deal other than that I got stuck wondering why I can only pass one letter.
// Single letter works
GLCDtinyPRINT (5, 5, "H")
// This generates an error Error: Duplicate, conflicting definition for DISPLAYTEXT
GLCDtinyPRINT (5, 5, "HELLO")
//This workaround works:
DIM sometext as String
sometext = "HELLO"
GLCDtinyPRINT (5, 5, sometext)
(The gcb file is attached)
Thank you. I undertand, And I thank you for the program.
The error is actually correct. The error caused by the definition of the variable in the sub
Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText ). ThedisplayTextas shown above will be defined as a byte. The default variable type is a byte. This is should be a string.* A byte can handle a string like "H". "H" is treated as a byte when passed to the sub.
*
GLCDtinyPRINT (5, 5, sometext)works assometextequates to an array. ( Strings in a variable are just Arrays ). So, each element is passed to the Sub as a byte.So,
"HELLO"fails as this string constant. The way to resolve.Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText as String )You can reduce the memory used by constraining the stringSub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText as String * 8 ). The* 8constrains to 8 bytes + 1 handler byte 9 bytes.So, the compiling will try to compile but will fail when you try a string constant.
This will fail. And this is correct.
This will work. And this is correct.
I hope this explains.
So, the compiler needs to know the number of letters to reserve, when sending it into the sub "directly" with the "oneliner" (no automatic buffer generated in this case). Good. Now I know.
Thank you for the explanation.
Not exactly correct. The compiler will allocate a standard size of RAM to use for the string. You can accept the default ( see the Help ) or adjust.
Yes, and each character in a string is one byte?
The standard size of RAM to use for the string is "40 bytes for devices with more RAM than 367 bytes"? -Unless the string is in the subroutine call, then the standard size is one byte. Right?
💬 String Byte Allocation
Yes, each character in a string occupies one byte, plus one additional byte for internal management.
Formula:
Number_of_bytes_allocated = 1 + (length of string)🧠 RAM Usage Guidelines for Strings
The standard RAM allocation for a string is 40 bytes, but only on devices with more than 367 bytes of RAM.
You can override the default size using the
* sizeconstruct.Example:
This creates a string of 8 characters, using 9 bytes of RAM (8 for content plus 1 for overhead).
You can pass a single character from a string to a subroutine or function using a
Bytevariable.As the ASCII value of the character (range: 0 to 255) is passed this is supported.
To pass a string type variable to a subroutine or function, you must use the correct type declaration (
String) in the subroutine or function definition.The string variable in the subroutine can be constrained to limit RAM usage.
Ensure the constrained string is large enough to accommodate the longest string that may be passed.
Attached is an update to improve the handling of this type of error.
Apply the update module by double clicking it will install the patch files. You will need the latest build of GC Studio. This MKV contains all the new files and you can remove safely using the module manager within GC Studio.
GCBASIC shared a post on Ko-fi. https://ko-fi.com/post/New-GC-Studio-Feature--A-Practical-Guide-to-F1F61N8WGD
I updated before seeing the video. I was a little confused by the "remove selected" but I took a chance, just went ahead and it just worked! How great is that! Now there is a understandable "problems" message generated when I try to run the code that I asked about. It used to say that there were no problems and I had to select and scroll "terminal" to find out about the problem, then not exactly understanding what it meant. The reason for this thread.
Thank you for the video explaining things, as well as the attention! :)
This is great news. Improved messages and a really simple way to fix and patch.
MPK was Angels idea and his implementation. Absolutely brilliant!!!
:-)
So I inserted my my code TinyStringtoGLCD PongyThingy Game and weird things happened.
I changed from GLCDPRINT (which worked fine) to GLCDtinyPRINT which used my TinyStringtoGLCD drawing routine. As long as I only used it to print the ScoreR and ScoreL strings I could get it to work, but If I inserted the code line for "GAME OVER", then the screen would neither print ScoreR nor ScroreL, DESPITE that the condition for "GAME OVER" had not yet occured!
Then at gameover condition I could sometimes get it to print "game over", but after that the screen got corrupted, the text ending up in the wrong place and next time I tried to print anything a bunch of distortions. I had to cut the power to the circuit and restart it.
I tried fiddling with the displayText as string x10 and even at x40 it would not work ("game over" is the longest string). Then at last I tried using only "displayText as string" (not ...string*10) and it started working. Huh??? Does this * size construct need resetting? Or what may be the cause?
sub scoreprint
GLCDtinyPRINT (44, 10, Bytetostring(ScoreR))
GLCDtinyPRINT (15, 10, Bytetostring(ScoreL))
If ScoreR = 11 or ScoreL = 11 Then
GLCDtinyPRINT (10, 20,"GAME OVER") //= problems when using size construct *10
wait 5 s
startgame 'start new game
end if
end sub
Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText as string10)
//removing the 10 makes it work. 30 or40 didn't work either
Last edit: Roger Jönsson 5 days ago
Can you try this ? I am interested in the results on real silicon.
The difference here is the string is defined in the sub. I have done this is the past.
Let me know what happens.
It works! It prints fine with it! 30 bytes saved.
Oddly, if I try:
Then it still prints "GAME OVER" and further 8 bytes are saved.
Seems to me that it is passing the string/bytes one by one(?), or what may be happening?
From 429 bytes, to 399, to 391
and 38 bytes saved.
Last edit: Roger Jönsson 5 days ago
That is what I call clever. Huge saving.
I am going to ask Hugh to explain what is going on here. But, we have a method.... define the string in the sub and I would set to the correct string size. It is not passing one character - this asm shows this.
Be back on this... later. Hugh can take a long time to respond.
Right, the whole string seems to be passed (why didn't I test this yesterday...) Len(displayText) is 9 bytes with "GAME OVER" for all below cases.
TinyStringtoGLCDinasub.html reports:
...
Chip resource usage:
Chip Model: 16F15376
...
Dim displayText as string * 1 :
Program Memory: 921/16384 words (5.62%)
RAM: 340/2048 bytes (16.6%)
Dim displayText as string * 10 :
Program Memory: 921/16384 words (5.62%)
RAM: 348/2048 bytes (16.99%)
Dim displayText as string :
Program Memory: 921/16384 words (5.62%)
RAM: 378/2048 bytes (18.46%)
...
If I print only "game" (with Dim displayText as string * 1 ) then RAM use drops further
RAM: 335/2048 bytes (16.36%)
The same if I print "GAME" and then "OVER" -still 335 bytes.
"GAME" and then "OVER2" = 336 bytes.
So the extra RAM consumed with -Dim displayText as string x whatever - seems not being used and the string is in some other special place that is proportional to the largest string size in the code.
Yes. We have a solution but I want to know what is going on. :=)
A dramatic nail biter! :)
Feeding this to the sub, total use of RAM in my program is 371bytes:
Replacing with this = 335 bytes:
In both cases the * x in the Dim displayText as string * x does not seem to affect the result, only increasing RAM use. It does not work a constraint either.
However, putting the constraint/limitation - displayText as string * 2 - in the subroutine line, does limit and fix RAM to max 2 letters and only "GA" prints. But only has an effect for the string that is created outside the subroutine call:
Last edit: Roger Jönsson 3 days ago
This must related to the scope of the string. I need Hugh. :-)