Shop OBEX P1 Docs P2 Docs Learn Events
Using the Propeller's ROM Character Definitions with a graphical LCD display — Parallax Forums

Using the Propeller's ROM Character Definitions with a graphical LCD display

JohnR2010JohnR2010 Posts: 431
edited 2015-02-12 10:10 in Propeller 1
I'm trying use the bit Fonts encoded into the Propeller's ROM starting at 0x8000. Is there an easy way to pull out these encoded characters? From my understating each character is intermingled with the next charter on every other bit. ARRRGGG

What I'm trying to do is pull out each letter's pixels so I can send that to my LCD display. Before I go down this road of sorting out every other bit I thought I would ask if anyone knows of a trick or an object that does this already? I have got to be missing something!!

UPDATE to Post:

Here is a pic using the SHARP low power Memory LCD with the ROM Fonts. Thanks again for everyone who responded and special thanks to @ChrisGadd and @Duane Degn!

By the way when the Prop is running with the internal crystal (RCSLOW ) this whole PCB (mLCD and Propeller) is using 41uA.

attachment.php?attachmentid=113182
1024 x 1365 - 676K

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2015-02-11 14:26
    JohnR2010 wrote: »
    I'm trying use the bit Fonts encoded into the Propeller's ROM starting at 0x8000. Is there an easy way to pull out these encoded characters? From my understating each character is intermingled with the next charter on every other bit. ARRRGGG

    What I'm trying to do is pull out each letter's pixels so I can send that to my LCD display. Before I go down this road of sorting out every other bit I thought I would ask if anyone knows of a trick or an object that does this already? I have got to be missing something!!

    I know I've done this and I thought it was pretty difficult. After doing this to display the ROM font on LED arrays, I've since found several sources of pulling the data from the ROM which are much cleaner than what I came up with.

    There's an SPI OLED driver in the OBEX which has a routine for doing this. I'll see if I can find a link.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2015-02-11 14:27
    Here's a good thread. Not only doesn't it pull the font from ROM but it resizes the font.

    http://forums.parallax.com/showthread.php/101194
  • Don MDon M Posts: 1,652
    edited 2015-02-11 15:28
    Interesting that there was reference to Prop2 in post #13. That was 7 years ago...
  • JohnR2010JohnR2010 Posts: 431
    edited 2015-02-11 16:02
    Thanks Duane! I cant follow what they are doing. I need to just walk away and hit this again tomorrow morning.. Thanks again for the link!!
  • RaymanRayman Posts: 14,652
    edited 2015-02-11 17:26
    Hey, you found Clemen's secret font! I've used it several times for projects...
    I've got assembly code somewhere that spits it out fast...
    This can be very useful in certain cases.
    You might try to dig up my old PSM code examples if you need it...
  • Cluso99Cluso99 Posts: 18,069
    edited 2015-02-11 17:51
    If it helps there is an 8x8 font known as AI???? which I believe hippy did.
    I have used this in my 1pinTV driver (obex). Its also used in a thread of mine driving the 1.44" color LCD.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2015-02-11 18:27
    Here's the method I wrote to display the ROM font on LED arrays.
    PUB MoveFontFromRomToRam(character, localPtr, ramWidth) | bytePtr, romPtr, firstOfPixelRow, {
    } firstOfArrayRow, pixelPtr, scratchBit, oddFlag, bytePerRowOfBuffer
    '' Only use this method when array is 32 pixels high.
    
      bytePerRowOfBuffer := 8 * ramWidth
      oddFlag := character & 1
     
      bytePtr := firstOfArrayRow := firstOfPixelRow := localPtr
       
      romPtr := $8000 + ((character / 2) * 128)
     
      if character => 32 and character =< 126
     
      repeat 4
        repeat 8
          result := long[romPtr]
          result ><= 32
          result := SquishLongAndSwap(result, oddFlag)
          pixelPtr := @result 
          repeat 2      
            bytemove(bytePtr, pixelPtr++, 1)
            bytePtr += 8
          romPtr += 4
          firstOfPixelRow++
          bytePtr := firstOfPixelRow
        firstOfArrayRow += bytePerRowOfBuffer '32
        bytePtr := firstOfPixelRow := firstOfArrayRow
    
      if rotatedFlag
        RotateArrays(localPtr, ramWidth * 4)
              
    PUB SquishLongAndSwap(longToSquish, oddFlag) | sourceBit, destinationBit, sourceToDestinationShiftAmount
    
      sourceBit := 1
      sourceToDestinationShiftAmount := 0
      ifnot oddFlag
        longToSquish >>= 1
      repeat 16  
        destinationBit := longToSquish & sourceBit
        destinationBit >>= sourceToDestinationShiftAmount
        result |= destinationBit
        sourceBit <<= 2
        sourceToDestinationShiftAmount += 1
     
      result.byte[2] := result.byte[1]
      result.byte[1] := result.byte[0]
      result.byte[0] := result.byte[2]
          
    

    "localPtr" is the memory address were the bitmap is to be placed. The variable "ramWidth" indicates how many bytes wide the bitmap is. The minimum value for "ramWidth" is 2 (16-bits).

    I'm pretty sure I can find another example of extracting the ROM font.
  • ChrisGaddChrisGadd Posts: 310
    edited 2015-02-11 18:29
    This should do the trick
    {{
      To find address of characters in ROM:           
       Clear the low bit of the character             "A" = $41                                                           
       Multiply value by 64                                 $40 x 64 = $1000                                                    
       Add result to a base offset of $8000                            $1000 + $8000 = $9000
       Read pattern from address, shift pattern for odd characters
       Display every other bit, starting from lsb (patterns are encoded in reverse)
       Increment address by 4 to read each following line
    }}
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      
    OBJ
      FDS : "FullDuplexSerial"
    
    PUB start | i, j
    
      FDS.start(31,30,0,115200)
      waitcnt(cnt + clkfreq)
      fds.tx($00)
      DisplayChar("C")
    
    PUB DisplayChar(char) | i
    
      repeat i from 0 to 31
        bin(long[char & !1 * $40 + $8000 + i * 4] ->= char & 1)                     
        fds.tx($0D)
    
    PUB Bin(value)
      repeat 16
        fds.Tx((value ->= 2) & 1 + "0")                 
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2015-02-11 18:39
    This is the method from the OLED driver in the OBEX.
    * OLED_AsmFast (well, faster)                  *
    * Thomas P. Sullivan
    
    PUB Write16x32Char(ch, row, col) | h, i, j, k, q, r, s, mask, cbase, cset, bset
    
      if row == 0 or row == 1 and (col => 0 and col < 8)
        ''Write a 16x32 character to the screen at position 0-7 (left to right)
        cbase := $8000 + ((ch & $FE) << 6)  ' Compute the base of the interleaved character 
          
        repeat j from 0 to 31       ' For all the rows in the font
          bset := |< (j // 8)       ' For setting bits in the OLED buffer.
                                    ' The mask is always a byte and has to wrap
          if ch & $01
            mask := $00000002       ' For the extraction of the bits interleaved in the font
          else
            mask := $00000001       ' For the extraction of the bits interleaved in the font
          r := long[cbase][j]       ' Row is the font data with which to perform bit extraction
          s := 0                    ' Just for printing the font  to the serial terminal (DEBUG)
          h := @buffer + row * 512  ' Get the base address of the OLED buffer
          h += ((j >> 3) * 128) + (col * 16)  ' Compute the offset to the column of data and add to the base...
                                    ' ...then add the offset to the character position
          repeat k from 0 to 15     ' For all 16 bits we need from the interlaced font...
            if r & mask             ' If the bit is set...
              byte[h][k] |= bset    ' Set the column bit
            else
              byte[h][k] &= !bset   ' Clear the column bit
            mask := mask << 2       ' The mask shifts two places because the fonts are interlaced
        if autoUpdate
          updateDisplay             ' Update the display
         
    
    

    Tom sure makes it look easy compared to the way I did it.

    As I said Tom's object is in the OBEX (I don't recall the name). I attached my version of the OLED driver to this post (there's a link to the OBEX driver there as well). I sped up the PASM SPI code.

    Edit: I hadn't seen Chris' post prior to making this one. His looks good too.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2015-02-11 18:45
    Cluso99 wrote: »
    If it helps there is an 8x8 font known as AI???? which I believe hippy did.
    I have used this in my 1pinTV driver (obex). Its also used in a thread of mine driving the 1.44" color LCD.

    The 8x8 RGB array Parallax sells has several different fonts in its code. I've manually entered (as ones and zeros) a "Free Design" font. I'm pretty sure I've posted these fonts to the forum in different forms. If anyone is interested in these and wants help finding them let me know.
  • JohnR2010JohnR2010 Posts: 431
    edited 2015-02-12 05:18
    Chris this is perfect. Your doing exactly what I want and in just two small methods. Well done sir and thanks very much for posting this!!
    ChrisGadd wrote: »
    This should do the trick
    PUB DisplayChar(char) | i
    
      repeat i from 0 to 31
        bin(long[char & !1 * $40 + $8000 + i * 4] ->= char & 1)                     
        fds.tx($0D)
    
    PUB Bin(value)
      repeat 16
        fds.Tx((value ->= 2) & 1 + "0")                 
    
  • JohnR2010JohnR2010 Posts: 431
    edited 2015-02-12 05:22
    Thanks Duane and others who posted here. You guys came through big time!!
  • potatoheadpotatohead Posts: 10,261
    edited 2015-02-12 10:06
    The AI GENERIC font was ripped from my Atari 400 ROM and was included in a lot of drivers, including AIGeneric.

    OBC packaged up a lot of other 8x8 fonts. I think those are in AIGeneric.

    I have an archive and links to many other fonts. If somebody needs one, let me know.
  • RaymanRayman Posts: 14,652
    edited 2015-02-12 10:10
    BTW: The neat thing about Clemen's secret font, is that it lets you scale down the ROM font to 8x16 in a way that looks nice for all the characters...
    I found the 16x32 ROM font too big for most small LCD applications. And, simply showing every other pixel to scale down doesn't look very nice.
Sign In or Register to comment.