Shop OBEX P1 Docs P2 Docs Learn Events
Looking for some help with code for scrolling up / down through buffer — Parallax Forums

Looking for some help with code for scrolling up / down through buffer

Don MDon M Posts: 1,652
edited 2013-05-08 22:20 in Propeller 1
Let's say I have a 2048 byte buffer that I dump messages into. Each message would end with an "03" (ETX) byte. Now I want to display them. I know I can do a repeat loop with indexing and an if statement to catch the 03 and stop going forward through. That part I understand.

But let's say I was scrolling forward and now I want to go backward a message at a time. How would that be done?

Any sample code or examples out there?

Comments

  • skylightskylight Posts: 1,915
    edited 2013-05-01 13:45
    I'm not sure about your code but if indexing i'd probably subtract and plus the index variable to go back and forward
  • Mike GreenMike Green Posts: 23,101
    edited 2013-05-01 14:54
    As skylight mentioned, you can go backwards through the buffer looking for the previous ETX code (or the beginning of the buffer). You can also store the length of the message both at the beginning and at the end of each message and use that to avoid scanning through the messages going forwards or backwards. It's also helpful to have pointers to both the start of the first message and the end of the last message.
  • Don MDon M Posts: 1,652
    edited 2013-05-07 13:22
    Here is what I have been working with to try and figure this out. I am using PST and in the preferences I only have 11, 13, 14, 15 checked.

    There is some sample data in the DAT section. Each line in the DAT section has a start character STX (02), the message, CR / LF and an ETX character (03). The data message in the DAT section is stored into a buffer called "message". I made 2 other buffers that store the charcter index position of each STX and ETX. These are marked in the code.

    What I'm trying to simulate is a "window" of 25 lines. By pressing the "f" key you will load the first 25 lines of the message. Each subsequent press of the "f" key will move the lines up one row and then display the newest line on the bottom. If you uncomment one line in the code (marked in the code as to which line) then it will only print 1 line at a time with each press of the "f" key until it gets to the 25th line then it will start at the top and work its way down moving the lines up 1 at a time.

    What I'm having a problem understanding is how do I go backward i.e. scroll down until I get to the beginning of the buffer?

    Also- is there an easier way to do what I have done here? I feel as though I made this harder than it needs to be but it has helped me learn this so far...

    Appreciate any and all help / comments.
    CON
            _clkmode = xtal1 + pll16x                                               'Standard clock mode * crystal frequency = 80 MHz
            _clkfreq = 80_000_000 
    
            MS_001   = 80_000_000 / 1_000  
    
    VAR
    
      byte  message[4096] ' The actual message itself
      word  messbeg[50]   ' Character index number for the beginning of each message
      word  messend[50]   ' Character index number for the end of each message
    
    OBJ
      term      : "FullDuplexSerial256"
      
    PUB Main | b, e, idx, i, line, r
    
      term.start(31, 30, %0000, 115_200)                    ' start terminal (use PST)
    
      pause(1000)
    
      line := 1                                             ' Line counter
      i := 0
      b := 0                                                ' Message beginning index
      e := 0                                                ' Message end index
    
      term.str(string("Data String Size: "))                ' Report number of characters in data message in dat section  
      term.dec(strsize(@data))
      term.tx(13)
    
      term.str(string("Writing Data to Message buffer.... "))
      repeat idx from 0 to 4095                             ' Copy data message from dat section to message buffer
        message[idx] := byte[@data][idx]
        case message[idx]                                   ' Test characters in data message...
          00:                                               ' If "00" it indicates end of message string. Stop saving to buffer
            quit
          02:                                               ' If "02" STX then store character number (index) to messbeg buffer
            messbeg[b++] := idx
          03:                                               ' If "03" ETX then store character number (index) to messend buffer 
            messend[e++] := idx
           
      term.dec(idx)                                         ' Indicate how many characters transferred. Should be same as data string size above.     
      term.str(string(" Characters. Done",13))
    
      i := 0                                                ' Initialize i
    
      term.tx(14)                                           ' Set cursor to Home
      term.tx(0)
      term.tx(15)
      term.tx(0)
    
      repeat
        r := term.rxcheck
        if r > -1
          case r
            "f":                                            ' Forward
              repeat idx from messbeg[i] to 4095            ' Repeat characters indexed by the beginning message pointer in messbeg
                term.tx(byte[@message][idx])
                case byte[@message][idx]                    ' Test byte looking for STX, ETX or end of message
                  00:                                       ' End of data message string
                    term.tx(11)                             ' Clear to end of line  
                    term.str(string("End of data",13))
                    quit
                  02:                                       ' Begining of message STX                                         
                    term.tx(11)                             ' Clear to end of line        
                  03:                                       ' End of message ETX
                    line++
                    i++
                    'quit                                   ' Uncomment this to do 1 line at a time with each press of "f"
                case line
                  26:
                    term.tx(14)                             ' Set cursor to Home
                    term.tx(0)
                    term.tx(15)
                    term.tx(0)
                    i := i - 24                             ' Start top row at next line as indicated in messbeg buffer
                    line := 1                               ' Reset line index
                    quit   
    
    pub pause(ms) | t
    
      t := cnt
      repeat ms
        waitcnt(t += MS_001)
    
    DAT
    
    data    byte  02,"Command: Setup 31H            Validator Response: Up to 27 Bytes Z0 - Z26",10,10,13,03
    
            byte  02,"Z0 =      Bill Validator Feature (MDB) Level - 1 byte",10,13,03
            byte  02,"          Indicates current feature level of the bill validator. Currently defined",10,13,03 
            byte  02,"          levels are:",10,13,03 
            byte  02,"          Level 1 - does not support option bits. (Z1 = 01H)",10,13,03 
            byte  02,"          Level 2 - supports option bits.         (Z1 = 02H)",10,10,13,03 
    
            byte  02,"Z1 - Z2 = Country / Currency code - 2 bytes",10,13,03 
            byte  02,"          The packed BCD country / currency code of the bill validator can be",10,13,03 
            byte  02,"          sent in 2 different forms depending on the valuse of the left most",10,13,03 
            byte  02,"          BCD digit.",10,13,03 
            byte  02,"          If the left most digit is a 0, the International Telephone Code is used",10,13,03 
            byte  02,"          to indicate the country that the validator is set-up for. For example,",10,13,03  
            byte  02,"          the USA code is 00 01H (Z1 = 00, Z2 = 01).",10,13,03  
            byte  02,"          If the left most digit is a 1, the latest version of the ISO 4217 numneric",10,13,03   
            byte  02,"          currency code is used. For example, the code for the US dollar is 18 40H",10,13,03  
            byte  02,"          (Z1 = 18, Z2 = 40). All new designs after 2000 must use ISO 4217.",10,10,13,03 
    
            byte  02,"Z3 - Z4 = Bill Scaling Factor - 2 bytes",10,13,03 
            byte  02,"          All accepted bill values must be evenly divisble by this number. For USA",10,13,03 
            byte  02,"          it would be 00 64H (0100 decimal).",10,10,13,03 
    
            byte  02,"Z5 =      Decimal Places - 1 byte",10,13,03 
            byte  02,"          Indicates the number of decimal places on the credit display.",10,10,13,03 
    
            byte  02,"Z6 - Z7 = Stacker Capacity - 2 bytes",10,13,03 
            byte  02,"          Indicates the number of bills the stacker will hold.",10,10,13,03 
    
            byte  02,"Z8 - Z9 = Bill Security Levels - 2 bytes",10,13,03 
            byte  02,"          Indicates the security level for bill types 0 to 15. Since not all",10,13,03  
            byte  02,"          validators support multiple security levels, validators that do not have",10,13,03 
            byte  02,"          this feature must report a 'high' security level.",10,10,13,03 
    
            byte  02,"Z10 =     Escrow / No Escrow - 1 byte",10,13,03 
            byte  02,"          Indicates the escrow capability of the bill validator. If Z10 = 00H, the",10,13,03 
            byte  02,"          bill validator does not have escrow capability. If Z10 = FFH, the bill",10,13,03  
            byte  02,"          validator has escrow capability.",10,10,13,03 
    
            byte  02,"Z11-Z26 = Bill Type Credit - 16 bytes",10,13,03 
            byte  02,"          Indicates the value of the bill types 0 to 15. Values must be sent in",10,13,03 
            byte  02,"          ascending order. This number is the bill's monetary value divided by",10,13,03 
            byte  02,"          the bill scaling factor. Unused bill types are sent as 00H. Unsent bill",10,13,03 
            byte  02,"          types are assumed to be zero. FFH bills are assumed to be vend tokens.",10,13,03,0        
    
  • iammeriammer Posts: 4
    edited 2013-05-07 16:37
    Hi,

    The way I would do it is to have a method that just displays 25 lines (or less if the end is hit) starting at a specific index. Then when f or p is pressed increment or decrement the index and call the display method. However that would require rewriting chunks of the above. I came up with an easier to implement solution using your existing code. I just copied the block for the "f" keypress and added a "p" keypress section the only difference between that and the "f" section is that the index is decremented by 2 first. That seemed to do what you want.
    CON
            _clkmode = xtal1 + pll16x                                               'Standard clock mode * crystal frequency = 80 MHz
            _clkfreq = 80_000_000
    
    
            MS_001   = 80_000_000 / 1_000
    
    
    VAR
    
    
      byte  message[4096] ' The actual message itself
      word  messbeg[50]   ' Character index number for the beginning of each message
      word  messend[50]   ' Character index number for the end of each message
    
    
    OBJ
      term      : "FullDuplexSerial256"
    
    
    PUB Main | b, e, idx, i, line, r
    
    
      term.start(31, 30, 00, 115_200)                    ' start terminal (use PST)
    
    
      pause(1000)
    
    
      line := 1                                             ' Line counter
      i := 0
      b := 0                                                ' Message beginning index
      e := 0                                                ' Message end index
    
    
      term.str(string("Data String Size: "))                ' Report number of characters in data message in dat section
      term.dec(strsize(@data))
      term.tx(13)
    
    
      term.str(string("Writing Data to Message buffer.... "))
      repeat idx from 0 to 4095                             ' Copy data message from dat section to message buffer
        message[idx] := byte[@data][idx]
        case message[idx]                                   ' Test characters in data message...
          00:                                               ' If "00" it indicates end of message string. Stop saving to buffer
            quit
          02:                                               ' If "02" STX then store character number (index) to messbeg buffer
            messbeg[b++] := idx
          03:                                               ' If "03" ETX then store character number (index) to messend buffer
            messend[e++] := idx
    
    
      term.dec(idx)                                         ' Indicate how many characters transferred. Should be same as data string size above.
      term.str(string(" Characters. Done",13))
    
    
      i := 0                                                ' Initialize i
    
    
      term.tx(14)                                           ' Set cursor to Home
      term.tx(0)
      term.tx(15)
      term.tx(0)
    
    
      repeat
        r := term.rxcheck
        if r > -1
          case r
            "f":                                            ' Forward
              repeat idx from messbeg[i] to 4095            ' Repeat characters indexed by the beginning message pointer in messbeg
                term.tx(byte[@message][idx])
                case byte[@message][idx]                    ' Test byte looking for STX, ETX or end of message
                  00:                                       ' End of data message string
                    term.tx(11)                             ' Clear to end of line
                    term.str(string("End of data",13))
                    quit
                  02:                                       ' Begining of message STX
                    term.tx(11)                             ' Clear to end of line
                  03:                                       ' End of message ETX
                    line++
                    i++
                    'quit                                   ' Uncomment this to do 1 line at a time with each press of "f"
                case line
                  26:
                    term.tx(14)                             ' Set cursor to Home
                    term.tx(0)
                    term.tx(15)
                    term.tx(0)
                    i := i - 24                             ' Start top row at next line as indicated in messbeg buffer
                    line := 1                               ' Reset line index
                    quit
            "p":
              if i>1
                i-=2
              else
                i:=0                                        ' back to previous line
              repeat idx from messbeg[i] to 4095            ' Repeat characters indexed by the beginning message pointer in messbeg
                term.tx(byte[@message][idx])
                case byte[@message][idx]                    ' Test byte looking for STX, ETX or end of message
                  00:                                       ' End of data message string
                    term.tx(11)                             ' Clear to end of line
                    term.str(string("End of data",13))
                    quit
                  02:                                       ' Begining of message STX
                    term.tx(11)                             ' Clear to end of line
                  03:                                       ' End of message ETX
                    line++
                    i++
                    'quit                                   ' Uncomment this to do 1 line at a time with each press of "f"
                case line
                  26:
                    term.tx(14)                             ' Set cursor to Home
                    term.tx(0)
                    term.tx(15)
                    term.tx(0)
                    i := i - 24                             ' Start top row at next line as indicated in messbeg buffer
                    line := 1                               ' Reset line index
                    quit
    
    
    pub pause(ms) | t
    
    
      t := cnt
      repeat ms
        waitcnt(t += MS_001)
    
    
    DAT
    
    
    data    byte  02,"Command: Setup 31H            Validator Response: Up to 27 Bytes Z0 - Z26",10,10,13,03
    
    
            byte  02,"Z0 =      Bill Validator Feature (MDB) Level - 1 byte",10,13,03
            byte  02,"          Indicates current feature level of the bill validator. Currently defined",10,13,03
            byte  02,"          levels are:",10,13,03
            byte  02,"          Level 1 - does not support option bits. (Z1 = 01H)",10,13,03
            byte  02,"          Level 2 - supports option bits.         (Z1 = 02H)",10,10,13,03
    
    
            byte  02,"Z1 - Z2 = Country / Currency code - 2 bytes",10,13,03
            byte  02,"          The packed BCD country / currency code of the bill validator can be",10,13,03
            byte  02,"          sent in 2 different forms depending on the valuse of the left most",10,13,03
            byte  02,"          BCD digit.",10,13,03
            byte  02,"          If the left most digit is a 0, the International Telephone Code is used",10,13,03
            byte  02,"          to indicate the country that the validator is set-up for. For example,",10,13,03
            byte  02,"          the USA code is 00 01H (Z1 = 00, Z2 = 01).",10,13,03
            byte  02,"          If the left most digit is a 1, the latest version of the ISO 4217 numneric",10,13,03
            byte  02,"          currency code is used. For example, the code for the US dollar is 18 40H",10,13,03
            byte  02,"          (Z1 = 18, Z2 = 40). All new designs after 2000 must use ISO 4217.",10,10,13,03
    
    
            byte  02,"Z3 - Z4 = Bill Scaling Factor - 2 bytes",10,13,03
            byte  02,"          All accepted bill values must be evenly divisble by this number. For USA",10,13,03
            byte  02,"          it would be 00 64H (0100 decimal).",10,10,13,03
    
    
            byte  02,"Z5 =      Decimal Places - 1 byte",10,13,03
            byte  02,"          Indicates the number of decimal places on the credit display.",10,10,13,03
    
    
            byte  02,"Z6 - Z7 = Stacker Capacity - 2 bytes",10,13,03
            byte  02,"          Indicates the number of bills the stacker will hold.",10,10,13,03
    
    
            byte  02,"Z8 - Z9 = Bill Security Levels - 2 bytes",10,13,03
            byte  02,"          Indicates the security level for bill types 0 to 15. Since not all",10,13,03
            byte  02,"          validators support multiple security levels, validators that do not have",10,13,03
            byte  02,"          this feature must report a 'high' security level.",10,10,13,03
    
    
            byte  02,"Z10 =     Escrow / No Escrow - 1 byte",10,13,03
            byte  02,"          Indicates the escrow capability of the bill validator. If Z10 = 00H, the",10,13,03
            byte  02,"          bill validator does not have escrow capability. If Z10 = FFH, the bill",10,13,03
            byte  02,"          validator has escrow capability.",10,10,13,03
    
    
            byte  02,"Z11-Z26 = Bill Type Credit - 16 bytes",10,13,03
            byte  02,"          Indicates the value of the bill types 0 to 15. Values must be sent in",10,13,03
            byte  02,"          ascending order. This number is the bill's monetary value divided by",10,13,03
            byte  02,"          the bill scaling factor. Unused bill types are sent as 00H. Unsent bill",10,13,03
            byte  02,"          types are assumed to be zero. FFH bills are assumed to be vend tokens.",10,13,03,0
    
  • kwinnkwinn Posts: 8,697
    edited 2013-05-08 22:20
    Why use both a start and end character when all you need is a start, end, and current position pointer along with a single message separator character?

    Start your 2048 character buffer with ETX as the first character and have each message terminated with an ETX.
    Have a single method that scans up or down depending on the parameter it is called with.
    Something like: " scan(curr_pos, 1)" to scan forward and "scan(curr_pos, -1) to go backwards.
Sign In or Register to comment.