Implement Text_Load/ShowString
authorTero Marttila <terom@fixme.fi>
Mon, 30 Aug 2010 00:45:38 +0300
changeset 39 d7eac199d323
parent 38 f430b507a885
child 41 fe9f354dddd4
child 42 99a179b64e6a
Implement Text_Load/ShowString
Makefile
font-compile.py
font.inc
font.txt
matrix.inc
matrix.s
--- a/Makefile	Sun Aug 29 22:49:32 2010 +0300
+++ b/Makefile	Mon Aug 30 00:45:38 2010 +0300
@@ -13,7 +13,7 @@
 
 all: $(PROG).hex
 
-matrix.hex: spi.inc matrix.inc timer.inc delay.inc macros.inc font.inc
+matrix.hex: spi.inc matrix.inc timer.inc delay.inc macros.inc font.inc font.def
 led7seg.hex: spi.inc led7seg.inc adc.inc timer.inc delay.inc macros.inc
 timer.hex: timer.inc macros.inc
 
--- a/font-compile.py	Sun Aug 29 22:49:32 2010 +0300
+++ b/font-compile.py	Mon Aug 30 00:45:38 2010 +0300
@@ -50,8 +50,14 @@
 
                 # skip
                 return None
+
+            elif len(ascii) == 1 :
+                print 'read_charblock', 'simplechar', ascii
+
+            else :
+                ascii = ascii.decode('string_escape')
         
-            print 'read_charblock', 'ascii', ascii
+                print 'read_charblock', 'decodechar', ascii
 
             assert len(ascii) == 1
         
@@ -119,7 +125,7 @@
     """
 
     fh.write(
-            ("; '%s'\n" % ascii)
+            ("; %r\n" % ascii)
         +   (".db %s\n" % (', '.join(bin(col) for col in cols)))
         +   ("\n")
     )
@@ -143,9 +149,11 @@
         charmap[ascii] = cols
 
         print 'compile_fonts', 'read', ascii
-    
-    font_start = '0'
-    font_end = '9'
+
+    # detect min/max syms
+    syms = charmap.keys()
+    font_start = min(syms)
+    font_end = max(syms)
 
     assert(ord(font_start) < ord(font_end))
     
@@ -153,17 +161,20 @@
     outf.write(
             ";; AUTOMATICALLY GENERATED - Do not edit!\n"
             ";; 8x6 font, '0' - '1', rows-by-col format\n"
-        +  (".equ FONT_8x6_START = %d ; '%s'\n" % (ord(font_start), font_start))
-        +  (".equ FONT_8x6_END = %d ; '%s'\n" % (ord(font_end), font_end))
+        +  (".equ FONT_8x6_START = %d ; %r\n" % (ord(font_start), font_start))
+        +  (".equ FONT_8x6_END = %d ; %r\n" % (ord(font_end), font_end))
         +  (".equ FONT_8x6_COLS = %d\n" % (6, ))
         +  (".equ FONT_8x6_ROWS = %d\n" % (8, ))
         +   "FONT_8x6:\n"
             "\n"
     )
 
-    for char in xrange(ord('0'), ord('9') + 1) :
+    # default symbol for unknown chars
+    defsym = charmap['\0']
+
+    for char in xrange(ord(font_start), ord(font_end) + 1) :
         ascii = chr(char)
-        cols = charmap[ascii]
+        cols = charmap.get(ascii, defsym)
 
         write_chardef(outf, ascii, cols)
 
--- a/font.inc	Sun Aug 29 22:49:32 2010 +0300
+++ b/font.inc	Mon Aug 30 00:45:38 2010 +0300
@@ -23,17 +23,26 @@
         ; test under-range
         ldi     r17, FONT_START
         cp      r16, r17
-        brlt    f_render_invalid
+        brlt    font_r_invalid
 
         ; test over-range
         ldi     r17, FONT_END
         cp      r17, r16
-        brlt    f_render_invalid
+        brlt    font_r_invalid
 
-    ; Locate font char
         ; compute offset in chars (r16)
         subi    r16, FONT_START
 
+        ; ok
+        rjmp    font_r_render
+
+font_r_invalid:
+        ; use first sym
+        ldi     r16, 0
+
+    cbi         PORTD, PIND7
+
+font_r_render:
         ; compute offset in bytes (r1:r0)
         ldi     r17, FONT_COLS
         mul     r16, r17
@@ -49,16 +58,15 @@
     ; Copy column pixel data
         ; count columns
         ldi     r16, FONT_COLS
-f_render_cpy:
+font_r_cpy:
         
         ; copy via r17
         lpm     r17, Z+
         st      Y+, r17
 
         dec     r16
-        brne    f_render_cpy
+        brne    font_r_cpy
 
-f_render_invalid:
 
     ; Done
         ret
--- a/font.txt	Sun Aug 29 22:49:32 2010 +0300
+++ b/font.txt	Mon Aug 30 00:45:38 2010 +0300
@@ -1,3 +1,33 @@
+; \x00
+------
+-####-
+-#--#-
+-#--#-
+-#--#-
+-#--#-
+-####-
+------
+
+; \x20
+------
+------
+------
+------
+------
+------
+------
+------
+
+; !
+--##--
+--##--
+--##--
+--##--
+--##--
+------
+--##--
+--##--
+
 ; 0
 -####-
 #----#
@@ -98,6 +128,76 @@
 -----#
 ----#-
 
+; h
+#-----
+#-----
+#-----
+#-----
+#-###-
+##---#
+#----#
+#----#
+
+; e
+--##--
+-#--#-
+#----#
+######
+#-----
+#---#-
+-###--
+------
+
+; l
+--##--
+---#--
+---#--
+---#--
+---#--
+---#--
+---#--
+--###-
+
+; o
+------
+------
+------
+-####-
+#----#
+#----#
+#----#
+-####-
+
+; w
+------
+------
+------
+#---#-
+#---#-
+#---#-
+#-#-#-
+-#-#--
+
+; r
+------
+------
+#-----
+#-##--
+##----
+#-----
+#-----
+#-----
+
+; d
+----#-
+----#-
+----#-
+-####-
+#---#-
+#---#-
+#---#-
+-###--
+
 ; 
 ------
 ------
--- a/matrix.inc	Sun Aug 29 22:49:32 2010 +0300
+++ b/matrix.inc	Mon Aug 30 00:45:38 2010 +0300
@@ -39,6 +39,17 @@
 ; this determines the starting offset for the visible viewport's left edge from the start of the framebuffer in columns
 matrix_colshift:    .byte 1                 ; viewport left column offset
 
+
+;; Text
+; Maximum length of message
+.set TEXT_MAXLENGTH = 64
+
+; Scrolling speed (kiloticks per frame)
+.set TEXT_SPEED = 1
+
+text_buffer:        .byte TEXT_MAXLENGTH    ; display message buffer
+text_offset:        .byte 1                 ; current offset in text
+
 .cseg
 
 ;; Normalize the outputs, enable the matrix, and set up buffers
@@ -258,3 +269,155 @@
         ; done
         ret
 
+;; Rewinds the currently visible viewport to the beginning of the framebuffer
+; This copies the currently visible viewport data to the beginning of the framebuffer and resets the offset
+Matrix_ShiftRewind:
+        ; current view offset
+        ldi         XL, low(matrix_colbuf)
+        ldi         XH, high(matrix_colbuf)
+
+        ; offset
+        lds         r16, matrix_colshift
+
+        ; add
+        ldi         r17, 0
+        add         XL, r16
+        adc         XH, r17
+
+        ; start of framebuffer
+        ldi         YL, low(matrix_colbuf + 0)
+        ldi         YH, high(matrix_colbuf + 0)
+
+        ; viewport width
+        ldi         r17, MATRIX_COLS
+
+matrix_shiftrew_loop:
+        ; copy
+        ld          r16, X+
+        st          Y+, r16
+
+        ; count
+        dec         r17
+        brne        matrix_shiftrew_loop
+
+        ; done, reset offset
+        rjmp        MAtrix_ShiftZero
+
+
+;; Load a NUL-terminated ASCII string from PGM into the text buffer
+; Input:    Z       - Address of NUL-terminated ASCII string in PGM        
+Text_LoadString:
+    ; Setup
+        ; storage buffer
+        ldi         YL, low(text_buffer)
+        ldi         YH, high(text_buffer)
+
+        ; max. length
+        ldi         r18, TEXT_MAXLENGTH
+
+text_loads_loop:
+    ; Test max length
+        ; count and check for overflow
+        dec         r18
+        brne        text_loads_char
+
+    ; Load char
+        ; force NUL
+        ldi         r16, 0x00
+
+text_loads_char:
+        ; load next char
+        lpm         r16, Z+
+
+text_loads_store:
+    ; Store and test NUL
+        ; store it
+        st          Y+, r16
+
+        ; test for NUL
+        tst         r16
+        brne        text_loads_loop
+
+    ; Update scroll offset
+        ; reset offset
+        ldi         r17, 0
+        sts         text_offset, r17
+
+        ; done
+        ret
+
+;; Shows the loaded string of ASCII text on the display, scrolling it horizontally
+; Uses font.inc for rendering
+; XXX: uses blocking timer sleeps and doesn't return until done
+Text_ShowString:
+    ; Load initial char
+        ldi         XL, low(text_buffer + 0)
+        ldi         XH, high(text_buffer + 0)
+
+        ; load char
+        ld          r16, X+
+        push        XL
+        push        XH
+
+        ; one column spacing
+        ldi         YL, low(matrix_colbuf + 1)
+        ldi         YH, high(matrix_colbuf + 1)
+
+        ; render to framebuffer
+        rcall       Font_Render
+
+        ; reset viewport
+        rcall       Matrix_ShiftZero
+       
+   ; Load next char
+text_shows_next:        
+        ; next char
+        pop         XH
+        pop         XL
+        ld          r16, X+
+        push        XL
+        push        XH
+
+        ; test NUL
+        tst         r16
+        breq        text_shows_end
+
+        ; offscreen
+        ldi         YL, low(matrix_colbuf + 1 + 6 + 1)
+        ldi         YH, high(matrix_colbuf + 1 + 6 + 1)
+
+        ; render
+        rcall       Font_Render
+
+    ; Animate to next char
+        ldi         r20, 7
+        
+text_shows_animloop:
+        ; sleep
+        ldi         XH, high(TEXT_SPEED * 1024)
+        ldi         XL, low(TEXT_SPEED * 1024)
+
+        rcall       Timer_Sleep
+
+        ; shift
+        rcall       Matrix_ShiftRight
+
+        ; count
+        dec         r20
+        brne        text_shows_animloop
+
+    ; Rewind to next char
+        rcall       Matrix_ShiftRewind
+
+        sbi         PIND, PIND7
+
+        ; load next char and animate it in
+        rjmp        text_shows_next
+
+text_shows_end:
+    ; Done
+        pop         XH
+        pop         XL
+
+        ret
+
--- a/matrix.s	Sun Aug 29 22:49:32 2010 +0300
+++ b/matrix.s	Mon Aug 30 00:45:38 2010 +0300
@@ -202,33 +202,23 @@
 
 Main_ScanText:
 
-stxt_start:
-        ; char to render
-        ldi         r24, 48 ; '0'
+    ; Constants
+stxt_message:       ; text to render
+        .db         0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x0 ; 'hello world!'
 
-    ; Render char
-stxt_loop:
-        ; target buffer
-        ldi         YL, low(matrix_colbuf + 0)
-        ldi         YH, high(matrix_colbuf + 0)
-        
-        ; render r24 to Y
-        mov         r16, r24
-        rcall       Font_Render
+    ; Load into buffer
+        ldi         ZL, low(stxt_message * 2)
+        ldi         ZH, high(stxt_message * 2)
 
-    ; Wait
-        ldi         XH, high(10 * 1024)
-        ldi         XL, low(10 * 1024)
-
-        rcall       Timer_Sleep
+        rcall       Text_LoadString
 
-    ; Next char
-        inc         r24
-        cpi         r24, 57 + 1 ; '9'
-        brsh        stxt_start        ; start again from zero
+sbi         PORTD, PIND7
 
-        ; render this char
-        rjmp        stxt_loop
+    ; Display
+        rcall       Text_ShowString
+
+    ; Done
+        ret
 
 Main:
 init: