Menu

String parameter to Subroutine fails if more than one letter.

2025-10-18
4 days ago
  • Roger Jönsson

    Roger Jönsson - 2025-10-18

    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?

     
  • Anobium

    Anobium - 2025-10-19

    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
      '''@param StringLocX X coordinate for message
      '''@param CharLocY Y coordinate for message
      '''@param Chars String to display
      '''@param LineColour Line Color, either 1 or 0
    Sub GLCDDrawChar(In CharLocX as word, In CharLocY as word, In CharCode, Optional In LineColour as word = GLCDForeground )
    
    //  Do stuff then call PSET()
    
    End Sub
    

    Much easier.

     
  • Roger Jönsson

    Roger Jönsson - 2025-10-19

    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)

     
  • Anobium

    Anobium - 2025-10-19

    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
  • Roger Jönsson

    Roger Jönsson - 2025-10-19

    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.

     
    • Anobium

      Anobium - 2025-10-19

      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.

       
  • Roger Jönsson

    Roger Jönsson - 2025-10-19

    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?

     
    • Anobium

      Anobium - 2025-10-20

      💬 String Byte Allocation

      “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
  • Anobium

    Anobium - 2025-10-23

    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.

     
    👍
    1
  • Roger Jönsson

    Roger Jönsson - 2025-10-23

    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! :)

     
    • Anobium

      Anobium - 2025-10-23

      This is great news. Improved messages and a really simple way to fix and patch.

      MPK was Angels idea and his implementation. Absolutely brilliant!!!

      :-)

       
      🎉
      1
  • Roger Jönsson

    Roger Jönsson - 5 days ago

    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
  • Anobium

    Anobium - 5 days ago

    Can you try this ? I am interested in the results on real silicon.

    Sub GLCDtinyPRINT (smallfont_positionX, smallfont_positionY, displayText as string )
        Dim displayText as string * 10
    

    The difference here is the string is defined in the sub. I have done this is the past.

    Let me know what happens.

     
  • Roger Jönsson

    Roger Jönsson - 5 days ago

    It works! It prints fine with it! 30 bytes saved.

    Oddly, if I try:

    Dim displayText as string * 1
    

    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
  • Anobium

    Anobium - 4 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.

     
  • Roger Jönsson

    Roger Jönsson - 4 days ago

    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.

     
    • Anobium

      Anobium - 4 days ago

      Yes. We have a solution but I want to know what is going on. :=)

       
  • Roger Jönsson

    Roger Jönsson - 4 days ago

    A dramatic nail biter! :)

    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
    • Anobium

      Anobium - 4 days ago

      This must related to the scope of the string. I need Hugh. :-)

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.