Shop OBEX P1 Docs P2 Docs Learn Events
Is there a PST equivalent to run on Ray's LCD screens? — Parallax Forums

Is there a PST equivalent to run on Ray's LCD screens?

Don MDon M Posts: 1,653
edited 2012-12-13 18:40 in Propeller 1
I would like to be able to display what I have been displaying on PST on my pc to the LCD display instead. How does one go about this? Is there already some code out there for this?

Thanks.
Don

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2012-12-13 10:07
    Ray has supplied a driver for the LCD screens that behaves like the TV driver and the PST driver is supposed to be a substitute for the TV_Text driver. You should be able to pretty much just drop in one of Ray's drivers. Have a look at Ray's demos. I think some of the control codes work the same, but Ray's driver only implements some of them.
  • Don MDon M Posts: 1,653
    edited 2012-12-13 10:35
    Are you talking about PSB_LcdDriver.spin?
  • RaymanRayman Posts: 14,826
    edited 2012-12-13 10:57
    Don, Mike is right of course, the driver you mention works very much like the VGA driver...
    I may not have a scrolling text example exactly like you want, but the "PSB_VGA_Demo" on this page:
    http://www.rayslogic.com/Propeller/Products/PSB/PSB_Display.htm

    should be fairly easily adapted to do what you want...
  • Don MDon M Posts: 1,653
    edited 2012-12-13 12:25
    Okay I have been playing with it for a bit and my ultimate goal would be to have it work somewhat like FDS in that I can send it a string to print or dec or hex, etc. like you do with FDS.

    I tried adding this method to get it to print a string from the dat section (I added the str method from FDS) your print method was already there:
    PUB print(c) | i, k
    
      case c
        $00..$FF:                   ' character?
          k := color << 1 + c & 1
          i := k << 10 + $200 + c & $FE
          screen[row * cols + col] := i
          screen[(row + 1) * cols + col] := i | 1
          if ++col == cols
            newline
    
        $100:                       ' clear screen?
          wordfill(@screen, $200, screensize)
          col := row := 0
    
        $108:                       ' backspace?
          if col
            col--
    
        $10D:                       ' return?  new line?
          newline
    
        $110..$11F:                 ' select color?
          color := c & $F
    
    PUB str(stringptr)
    
      '' Send zero terminated string that starts at the stringptr memory address
    
      repeat strsize(stringptr)
        print(byte[stringptr++])
    

    but it doesn't work right. In the beginning section of your demo you write to the screen like this:
    repeat i from 0 to 25
          print(something[i])
    
    

    but I was hoping to make it work more like FDS in that when it hits a zero terminated string it quits etc....
  • Don MDon M Posts: 1,653
    edited 2012-12-13 12:28
    Also what do I have to change to get smaller text?
  • Mike GreenMike Green Posts: 23,101
    edited 2012-12-13 12:33
    It does work like FDS. That's why there's an "str" method. "print" works just like "tx". This driver is patterned after TV_Text, so it has the same interface.

    To get smaller text, you have to work magic on the assembly language driver and provide any necessary font tables ... doable, but not a trivial change.
  • Don MDon M Posts: 1,653
    edited 2012-12-13 12:44
    I was thinking there were other drivers for smaller vga text?
  • Don MDon M Posts: 1,653
    edited 2012-12-13 13:46
    Mike Green wrote: »
    It does work like FDS. That's why there's an "str" method. "print" works just like "tx". This driver is patterned after TV_Text, so it has the same interface.

    Mike- I didn't see any str method in his demo or driver. The str method is what I added and treated the print as if it were tx.

    I got it working but I'm curious as to why the text does not stay on the screen after it is displayed unless there is a repeat loop or a long pause it will disappear.

    I'm trying to make this work as though it is a terminal. And just like FDS & PST if I send the charachters to it they remeain on the screen. Help me understand this object.
  • Don MDon M Posts: 1,653
    edited 2012-12-13 14:05
    Here's Ray's Demo program with the added str method> I deleted his graphic demo at the beginning and just added a simple print text routine. I did it 2 different ways. 1 using the repeat function and the other using the str method. With the str method I added a $10D which is supposed to trigger a newline but it doesn't. See the dat section. All it does is add 2 small horizontal lines in between "test" and "This".
    CON
    
      _clkmode = xtal1+pll16x
      _clkfreq = 80_000_000
    
      cols = 30
      rows = 17
      screensize = cols * rows
    
    VAR
    
      long  lcd_status      'status: off/visible/invisible  read-only       (5 contiguous longs)
      long  lcd_enable      'enable: off/on                 write-only
      long  lcd_videobase   'video base @word               write-only
      long  lcd_colorbase   'color base @long               write-only
      long  lcd_backlight   'Used to control LCD backlight
    
      word  screen[screensize]
    
      long  col, row, color
      long  boxcolor,ptr
      long  stack[100]
    
    OBJ
    
      vga : "PSB_LcdDriver"  'Modified to also drive TFT
    
    pub launch
    
      cognew(begin, @stack)
    
      repeat
    
    PUB begin: I
    
      Start  'Pins already defined in LCD driver
    
      print($100)                   ' clear screen
      print($113)                   ' set background color to black
    
      repeat i from 0 to 13         ' send message this way
        print(message[i])
        
      col := 0
      row := 6
      print($114)
    
      str(@message)  
    
      repeat                        '<<<<<< if this repeat is removed then the text goes away. Why?
        i := cnt
        waitcnt(i += 22500000)
        'spcl := $30101020
        waitcnt(i += 22500000)
        'spcl := $10301020
    
    '' Start terminal - starts a cog
    '' returns false if no cog available
    
    PUB start       
    
      print($100)
      'start driver
      lcd_enable:=1
      lcd_videobase := @screen
      lcd_colorbase := @vgacolors
      lcd_backlight:=3  '1=bright, 16=medium, 32=dark
      vga.start(@lcd_status)
    
    
    '' Stop terminal - frees a cog
    
    PUB stop      
    
      vga.stop
    
    '' Draw a box
    
    PUB box(left,top,width,height) | x, y, i          
    
      ptr := top * cols + left
      boxchr($0)
      repeat i from 1 to width
        boxchr($C)
      boxchr($8)
      repeat i from 1 to height
        ptr := (top + i) * cols + left
        boxchr($A)
        ptr += width
        boxchr($B)
      ptr := (top + height + 1) * cols + left
      boxchr($1)
      repeat i from 1 to width
        boxchr($D)
      boxchr($9)
    
    PRI boxchr(c): i
    
      screen[ptr++] := boxcolor << 10 + $200 + c
    
      
    
    '' Print a character
    ''
    ''  $00..$FF = character
    ''      $100 = clear screen
    ''      $108 = backspace
    ''      $10D = new line
    ''$110..$11F = select color
    
    PUB str(stringptr)              '<<<<<< I added this method from FDS
    
      '' Send zero terminated string that starts at the stringptr memory address
    
      repeat strsize(stringptr)
        print(byte[stringptr++])    '<<<< I changed this from tx to print
    
    PUB print(c) | i, k
    
      case c
        $00..$FF:           'character?
          k := color << 1 + c & 1
          i := k << 10 + $200 + c & $FE
          screen[row * cols + col] := i
          screen[(row + 1) * cols + col] := i | 1
          if ++col == cols
            newline
    
        $100:               'clear screen?
          wordfill(@screen, $200, screensize)
          col := row := 0
    
        $108:               'backspace?
          if col
            col--
    
        $10D:               'return?
          newline
    
        $110..$11F:         'select color?
          color := c & $F
    
    
    ' New line
    
    PRI newline : i
    
      col := 0
      if (row += 2) == rows
        row -= 2
        'scroll lines
        repeat i from 0 to rows-3
    '      wordmove(@screen[i*cols], @screen[(i+2)*cols], cols)
        'clear new line
    '    wordfill(@screen[(rows-2)*cols], $200, cols<<1)
    
    
    ' Data
    
    DAT
    
    message                 byte    "This is a test", $10D
                            byte    "This is line 2", 0
    
    vgacolors               long
                            long    $00000000       'black   red is C000C000 '<<<<< changed this to get black background
                            long    $C0C0C0C0       ' red    was  $C0C00000
                            long    $08A808A8       'green
                            long    $0808A8A8
                            long    $50005000       'blue
                            long    $50500000
                            long    $FC00FC00       'white
                            long    $FCFC0000
                            long    $FF80FF80       'red/white
                            long    $FFFF8080
                            long    $FF20FF20       'green/white
                            long    $FFFF2020
                            long    $FF28FF28       'cyan/white
                            long    $FFFF2828
                            long    $00A800A8       'grey/black
                            long    $0000A8A8
                            long    $C0408080       'redbox
    spcl                    long    $30100020       'greenbox
                            long    $3C142828       'cyanbox
                            long    $FC54A8A8       'greybox
                            long    $3C14FF28       'cyanbox+underscore
                            long    0
    

    So 2 questions-

    1. Why is a repeat needed after the strings are sent?
    2. Why doesn't the message from dat trigger a newline with the embedded $10D?
  • Don MDon M Posts: 1,653
    edited 2012-12-13 14:13
    Here's a photo of the screen to show what I'm talking about.

    20121213_161012.jpg
    1024 x 768 - 165K
  • kuronekokuroneko Posts: 3,623
    edited 2012-12-13 14:39
    Don M wrote: »
    2. Why doesn't the message from dat trigger a newline with the embedded $10D?
    You declared a byte array, which has the tendency to cut off everything bigger than 8bit (and $0D is not treated as CR).

    As for the display disappearing, the LCD driver sets some pins in the context of the caller's cog which - when you exit (no repeat) - return to their default state(s) therefore turning off the display.
  • Don MDon M Posts: 1,653
    edited 2012-12-13 15:06
    kuroneko wrote: »
    You declared a byte array, which has the tendency to cut off everything bigger than 8bit (and $0D is not treated as CR).

    Thanks. Gets me every time... changed the code to this. Changes marked (and it works):
    PUB print(c) | i, k
    
      case c
        $20..$7E:           '<<< changed from $00..$FF
          k := color << 1 + c & 1
          i := k << 10 + $200 + c & $FE
          screen[row * cols + col] := i
          screen[(row + 1) * cols + col] := i | 1
          if ++col == cols
            newline
    
        $100:               'clear screen?
          wordfill(@screen, $200, screensize)
          col := row := 0
    
        $108:               'backspace?
          if col
            col--
    
        $00D:               '<<<< changed from $10D
          newline           'return?         
    
        $110..$11F:         'select color?
          color := c & $F
    
    kuroneko wrote: »
    As for the display disappearing, the LCD driver sets some pins in the context of the caller's cog which - when you exit (no repeat) - return to their default state(s) therefore turning off the display.

    I don't quite understand this. Can you explain it in a different way?
  • Don MDon M Posts: 1,653
    edited 2012-12-13 15:11
    Also I changed the dat section too.. forgot to mention in previous post.
    DAT
    
    message                 byte    "This is a test", $0D
                            byte   "This is line 2", 0
    
  • kuronekokuroneko Posts: 3,623
    edited 2012-12-13 15:14
    Don M wrote: »
    I don't quite understand this. Can you explain it in a different way?
    In your begin method you start the LCD driver. Said method runs in cog A. Starting the LCD driver will also start a PASM cog (B). Additionally - if you look at its start method - it also manipulates DisplayOnPinA which is in the context of cog A (dira/outa). IOW, while the LCD PASM cog stays alive, exiting cog A (running your begin method) will also revert the DisplayOnPin settings.

    Effectively, in order to keep the display switched on, you have to keep cog A alive.


    A I'm aware it's conditional but given the described behaviour it's most likely active.
  • Don MDon M Posts: 1,653
    edited 2012-12-13 15:21
    kuroneko wrote: »
    In your begin method you start the LCD driver. Said method runs in cog A. Starting the LCD driver will also start a PASM cog (B). Additionally - if you look at its start method - it also manipulates DisplayOnPinA which is in the context of cog A (dira/outa). IOW, while the LCD PASM cog stays alive, exiting cog A (running your begin method) will also revert the DisplayOnPin settings.

    Effectively, in order to keep the display switched on, you have to keep cog A alive.


    A I'm aware it's conditional but given the described behaviour it's most likely active.

    Does it have to be done this way?
  • kuronekokuroneko Posts: 3,623
    edited 2012-12-13 15:25
    Don M wrote: »
    Does it have to be done this way?
    Keeping the display switched on? No. It's just the way it is. But I don't really see this as an issue, normally the cog using the display stays alive ...
  • Don MDon M Posts: 1,653
    edited 2012-12-13 15:54
    So is it just a matter of the display getting turned off? The characters are still there and it only needs to be turned back on is that how I understand it to be?
  • kuronekokuroneko Posts: 3,623
    edited 2012-12-13 16:06
    Don M wrote: »
    So is it just a matter of the display getting turned off? The characters are still there and it only needs to be turned back on is that how I understand it to be?
    From what you describe (i.e. keeping cog A alive keeps the display switched on) that's the case here. You could e.g. start the LCD driver in your launch method (which is kept alive as well) and only use it in your begin method. This way the latter can safely exit and the display should stay on.
  • Don MDon M Posts: 1,653
    edited 2012-12-13 16:41
    kuroneko wrote: »
    From what you describe (i.e. keeping cog A alive keeps the display switched on) that's the case here. You could e.g. start the LCD driver in your launch method (which is kept alive as well) and only use it in your begin method. This way the latter can safely exit and the display should stay on.

    Thanks for the suggestion. That works for now.

    Thanks for your help.
    Don
  • Don MDon M Posts: 1,653
    edited 2012-12-13 16:53
    Can you explain to me how this:
    print($113)          
    

    run through this method:
    PUB print(c) | i, k
    
      case c
        $20..$7E:           '<<< changed from $00..$FF
          k := color << 1 + c & 1
          i := k << 10 + $200 + c & $FE
          screen[row * cols + col] := i
          screen[(row + 1) * cols + col] := i | 1
          if ++col == cols
            newline
    
        $100:               'clear screen?
          wordfill(@screen, $200, screensize)
          col := row := 0
    
        $108:               'backspace?
          if col
            col--
    
        $00D:               '<<<< changed from $10D
          newline           'return?         
    
        $110..$11F:         'select color?
          color := c & $F
    

    somehow equates to a color from this:
    DAT
    
    message                 byte    "This is a test", 13
                            byte   "This is line 2", 0
    
    vgacolors               long
                            long    $00000000       'black   red is C000C000 '<<<<< changed this to get black background
                            long    $C0C0C0C0       ' red    was  $C0C00000
                            long    $08A808A8       'green
                            long    $0808A8A8
                            long    $50005000       'blue
                            long    $50500000
                            long    $FC00FC00       'white
                            long    $FCFC0000
                            long    $FF80FF80       'red/white
                            long    $FFFF8080
                            long    $FF20FF20       'green/white
                            long    $FFFF2020
                            long    $FF28FF28       'cyan/white
                            long    $FFFF2828
                            long    $00A800A8       'grey/black
                            long    $0000A8A8
                            long    $C0408080       'redbox
    spcl                    long    $30100020       'greenbox
                            long    $3C142828       'cyanbox
                            long    $FC54A8A8       'greybox
                            long    $3C14FF28       'cyanbox+underscore
                            long    0
    

    I have found the little program that Ray has on his website to configure the longs in the dat table for specific colors but I don't understand how they are referenced by the code above.
  • kuronekokuroneko Posts: 3,623
    edited 2012-12-13 16:59
    Don M wrote: »
    Can you explain ...

    Well, the parameter is $113 which will trigger
    $110..$11F:         'select color?
          color := c & $F
    
    in the case statement ($113 is within $110..$11F). The code will extract a 3 ($113 & $00F) from the parameter and therefore select color 3 for subsequent output.
  • Don MDon M Posts: 1,653
    edited 2012-12-13 17:02
    How is "color 3" corelated with the vgacolors table?
  • kuronekokuroneko Posts: 3,623
    edited 2012-12-13 17:11
    Don M wrote: »
    How is "color 3" corelated with the vgacolors table?
    If you look at the case statement for character printing:
    $20..$7E:           '<<< changed from $00..$FF
          k := [COLOR="#FF0000"]color[/COLOR] << 1 + c & 1
          i := k << 10 + $200 + c & $FE
          screen[row * cols + col] := i
          screen[(row + 1) * cols + col] := i | 1
          if ++col == cols
            newline
    
    You'll see the color variable being used to construct the word value written into the character buffer (screen[]). The VGA driver knows about the palette (see start method, lcd_colorbase) and internally selects the right colour during the display loop.

    Given that the selectable colour is in the range of 0..15 it suggests long indices into the colour table.
  • Don MDon M Posts: 1,653
    edited 2012-12-13 17:22
    Ok I still don't understand. Maybe I should ask another way. What if I wanted the color to be red characters on a black background. According to Rays website calculator red would be $C0C0C0C0 for all red from LSB -> MSB. I don't know if that defines just the background color, the character color or both. So if I were to insert in the dat table this long ($C0C0C0C0) in the list how would I index it, in other words how do I know which value to include in print($11?) for the color?
  • kuronekokuroneko Posts: 3,623
    edited 2012-12-13 18:00
    This driver is based on the ROM font VGA driver, each colour entry is two longs in size. The first is used for even (%-0) characters, the second one for odd (%-1) ones. If you look at the indices 8/9 (colour 4, white on red):
    long    $FF80FF80       'red/white
                            long    $FFFF8080
    
    The structure is dictated by the way the ROM font is encoded and stored. Even characters require an FBFB palette entry (Forground/Background), odd characters FFBB. So for red on black you'd need $C000C000 for the first entry and C0C00000 for the second. Put them into e.g. slot 0 and 1 then select colour $110 (slots are colour*2 + 0 and colour*2 + 1).
  • Don MDon M Posts: 1,653
    edited 2012-12-13 18:18
    kuroneko wrote: »
    The structure is dictated by the way the ROM font is encoded and stored. Even characters require an FBFB palette entry (Forground/Background), odd characters FFBB. So for red on black you'd need $C000C000 for the first entry and C0C00000 for the second. Put them into e.g. slot 0 and 1 then select colour $110 (slots are colour*2 + 0 and colour*2 + 1).

    Ok now that helps a ton. I tried what you mentioned and my table looks like this:
    DAT
    
    message                 byte    "This is a test", 13
                            byte   "This is line 2", 0
    
    vgacolors               long    
                            long    $C000C000     'black   red is C000C000 '<<<<< changed this to get black background
                            long    $C0C00000        ' red    was  $C0C00000
                            long    $08A808A8       'green
                            long    $0808A8A8
                            long    $50005000       'blue
                            long    $50500000
                            long    $FC00FC00       'white
                            long    $FCFC0000
                            long    $FF80FF80       'red/white
                            long    $FFFF8080
                            long    $FF20FF20       'green/white
                            long    $FFFF2020
                            long    $FF28FF28       'cyan/white
                            long    $FFFF2828
                            long    $00A800A8       'grey/black
                            long    $0000A8A8
                            long    $C0408080       'redbox
    

    the characters are red on black background but there is a funky background all around it. I don't know where that comes from. If I can get this figured out then I should have enough to get along on my own.

    Here's what it looks like:

    20121213_201321.jpg
    1024 x 768 - 221K
  • kuronekokuroneko Posts: 3,623
    edited 2012-12-13 18:27
    Don M wrote: »
    ... the characters are red on black background but there is a funky background all around it. I don't know where that comes from. If I can get this figured out then I should have enough to get along on my own.
    That's the top half of character 0. Try using $220 in the clear screen code (instead of $200), i.e. wordfill(@screen, $220, screensize).
  • Don MDon M Posts: 1,653
    edited 2012-12-13 18:40
    kuroneko - that fixed it. You're a true inspiration. Thanks so much for your help. I aspire to be as good with this code as you some day.

    Thanks again.
    Don
Sign In or Register to comment.