diff --git a/python/cat.py b/python/cat.py
index 87a9933c648bf4473166822ee978c6cc9d4232f4..29a19afea4f3f754801a00a9ae6eb12018bb90af 100644
--- a/python/cat.py
+++ b/python/cat.py
@@ -4,24 +4,8 @@ import sys
 import client
 
 # read lines from stdin and write them to the display.
-# includes scrolling.
-# FIXME: scrolling is slow. use a pixel buffer and blitting.
-if __name__ == "__main__":
-    y = 0
-    lines = []
+line = sys.stdin.readline()
+while(line != ""):
+    client.writeline(line)
     line = sys.stdin.readline()
-    while(line != ""):
-        client.write(0, y, line)
-        lines.append(line)
-        if(y == client.NUM_SEG_Y):
-            lines.reverse()
-            lines.pop()
-            lines.reverse()
-            y = 0
-            for l in lines:
-                client.write(0, y, l)
-                y += 1
-        else:
-            y += 1
-        line = sys.stdin.readline()
 
diff --git a/python/client.py b/python/client.py
index 58866d959dca3fbfee4a1ca8dd923611d45b0448..885cfe1f4a48c8b7d469b4fa5c2d92845acf5db9 100644
--- a/python/client.py
+++ b/python/client.py
@@ -111,10 +111,21 @@ def write(x, y, string):
         if(x > NUM_SEG_X):
             return False
 
-# write text at beginning of line and clear remaining horizontal space
-def writeline(y, string):
-    write(0, y, string)
-    write(len(string), y, ' ' * (NUM_SEG_X-len(string)))
+# write line to screen as if on a terminal, scroll up if neccessary
+cur_line = -1
+def writeline(string):
+    global cur_line
+    cur_line += 1
+    if(cur_line >= NUM_SEG_Y):
+        scrollline()
+        cur_line -= 1
+    write(0, cur_line, string)
+
+    # clear remaining row
+    clear_chars = (NUM_SEG_X-len(string))
+    screenbuf_blit(len(string) * PWIDTH, cur_line * PHEIGHT,
+        clear_chars * PWIDTH, PHEIGHT,
+        [0] * clear_chars * PWIDTH * PHEIGHT)
 
 # scroll the content y lines up and clear last line
 def scrollline(y = 1):