Shop OBEX P1 Docs P2 Docs Learn Events
question on LCD_STR subroutine — Parallax Forums

question on LCD_STR subroutine

mojorizingmojorizing Posts: 249
edited 2008-12-22 22:36 in General Discussion
Regarding this code:

' Use: LCD_STR [noparse][[/noparse] string | label ]
' -- "string" is an embedded literal string
' -- "label" is DATA statement label for stored z-String

LCD_STR:
  temp3 = __PARAM1                              ' get string offset
  temp4 = __PARAM2                              ' get string base
  DO
    READ temp4 + temp3, temp5                   ' read a character
    IF temp5 = 0 THEN EXIT                      ' if 0, string complete
    LCD_OUT temp5                            ' send the byte
    INC temp3                                   ' point to next character
    temp4 = temp4 + Z                           ' update base on overflow
  LOOP
  RETURN




This chunk of code is used by everyone to output a string of characters to an LCD. I've used it before, but now I'm having a senior moment. When used with a string, for example:
LCD_STR " I'm having a senior moment! "


1) How is _param2 assigned the base for the READ?
2) And likewise, how is _param1 the string offset. These two parameters aren't apparent when all there is is a string.

In the Help file for READ, it mentions that the compiler inserts appropriate values that form the pointer to the string. Please explain where I can see this because the LIST of this code doesn't answer my questions.

Thanks, Kevin

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Bad spellers of the world untie!

Comments

  • mojorizingmojorizing Posts: 249
    edited 2008-12-20 21:28
    I took a break and I went over to Youtube and watched a few rock videos from bands in the '70's, and my senior moment has passed!

    The LIST file does indeed show where the 2 parameters are massaged to work here. For example, in the code for SERIAL_LCD_DEMO.SXB LIST file , at the point of declaration of the statement
    LCD_STR " PARALLAX SX/B "
    

    the list file shows how the compiler inserts the correct values.

    Rock on and Merry Christmas!
    Kevin

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Bad spellers of the world untie!
  • JonnyMacJonnyMac Posts: 9,214
    edited 2008-12-20 23:02
    That's pretty old code -- you might want to rewrite it thusly:

    ' Use: TX_STR [noparse][[/noparse]String | Label]
    ' -- pass embedded string literal or DATA label (zString at label)
    
    SUB LCD_STR
      sAddr         VAR     tmpW1                   ' address of string
      sChar         VAR     __PARAM1                ' character from string
    
      sAddr = __WPARAM12                            ' copy address
    
      DO 
        READINC sAddr, sChar                        ' get a character
        IF sChar = 0 THEN EXIT                      ' if 0, we're done
        LCD_OUT sChar                               ' print the character
      LOOP
      ENDSUB
    


    You'll need to terminate any strings stored in DATA statements with a zero ( SX/B adds the zero for inline strings).

    Message:
      DATA  "JonnyMac rocks!", 0
    


    The compiler is able to resolve the address of an embedded string or DATA statement to a two-byte value. This can be passed to a subroutine in __WPARAM12 (__PARAM1 + __PARAM2), and as the address is passed as a variable the READINC instruction can be used to simplify the subroutine. I use is kind of subroutine in any of my programs that serialize character output.

    I've attached a 4-bit LCD demo for your reference.

    Post Edited (JonnyMac) : 12/20/2008 11:52:46 PM GMT
  • mojorizingmojorizing Posts: 249
    edited 2008-12-22 18:23
    Thanks for the help on this code. My final intention is to use a 4x20 LCD where I use text from a series of DATA tables with different levels of "menu's". The top level, for instance would be "entrees" (Ribeye steak,etc.), once an entree is selected (with the use of 3 push buttons,"Up" "Down""Select"), the next level would be "preparation" (well done, rare, etc.) My original code for these different options filled the 4x20 LCD with the proper text by keeping track of where I was in the selections, using a "branch" command to go to code that would fill 4 x 20 field from a series of LCD_STR's:

    .......
        LCD_OUT    LcdLine1
        LCD_STR "Mac and Cheese"    
        LCD_OUT    LcdLine2
        LCD_STR "Hamburger Helper"
            ..........
    



    Needless to say, doing it this way pretty much filled up the program memory with this text management scheme, leaving not enough program space for the real "meat" of the program. No pun intended.
    The crux of the problem is how to pull "RibEye steak" from this data field

    Menus:
        DATA      "Mac and Cheese     ", 0
        DATA    "Hamburger Helper  ", 0
        DATA    "RibEye Steak         ", 0
        DATA    "Pot Roast              ", 0
        DATA      "Cheese Burger      ", 0
    Dessert:
        DATA      "Angioplasty           ", 0
    



    using the LCD_STR subroutine. It seems I would need to load _param2 with the proper address for of the DW statement (from the LIST file). Also, if I use something similar to the "Animation" FOR-NEXT LOOP, I wouldn't need to use zero at the end of my statements, the FOR-NEXT LOOP would fill the line with the text.

    I've pared down your LCD_4 code to just this data field, and the animation loop, no custom characters, etc. Not included is my button pushing scheme, branching, etc.

    What are your thoughts on pulling text from DATA sections using the LCD_STR routine?

    Thanks, Kevin

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Bad spellers of the world untie!

    Post Edited (mojorizing) : 12/22/2008 6:31:22 PM GMT
  • mojorizingmojorizing Posts: 249
    edited 2008-12-22 19:47
    When I replace
    READ Menus + idx1, char
    

    in the animation loop with the assm. generated by the compiler than add 20, then I'm able to IREAD and print out on the LCD the next line of text "Hamburger Helper".

    Animation:
      FOR idx1 = 0 TO 15                        ' scroll across line
        \MOV __PARAM1,#Menus + 20 & 255       
            \MOV __PARAM2,#Menus >> 8        
            \ADD __PARAM1,idx1        
            \ADDB __PARAM2,C               
            \MOV M,__PARAM2        
            \MOV W,__PARAM1                
            \IREAD                         
            \MOV char,W                        
          pos = LcdLine2 + idx1
          LCD_OUT pos
          LCD_OUT char
          
      NEXT
    



    This means I could add the necessary offset to the menus address and start at the correct address for the text I need. This will work, but it's not very eloquent.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Bad spellers of the world untie!
  • JonnyMacJonnyMac Posts: 9,214
    edited 2008-12-22 21:54
    I'm actually starting on a project for my March N&V column that uses a 2x16 LCD and menu system. What I've attached is something quick that seems to work pretty well and should get you started; that said, I may improve it over the next couple weeks as I work on my time-lapse controller project.

    Note that I use READ with a table to get the string offsets -- this uses less code space than the * operator.
  • mojorizingmojorizing Posts: 249
    edited 2008-12-22 22:09
    Ok, JonnyMac, that's pretty slick! I like the way you handle the offset. I'm looking forward to your article.

    Thanks again and Merry Christmas

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Bad spellers of the world untie!
  • JonnyMacJonnyMac Posts: 9,214
    edited 2008-12-22 22:36
    You're welcome -- and if you find ways to improve the code please share. Merry Christmas to you and yours as well.
Sign In or Register to comment.