With regards to graphics, if one were to dedicate 2k of ram to a frame-buffer, you should be able to get ~5fps by just continuously rendering the frame-buffer to the graphics controller. setPixel is slow because it does 2 r/m/w per pixel, but rendering an already known 8 pixel block would do two writes per block or 1/4 write per pixel for an 8x speedup.
This could be further optimized by keeping a map of dirty/clean bits for each character; then you could just add to the game loop something that polls the ready bit on the latch and writes the next dirty character.
Your setPixel now becomes (read from frame buffer, write if different, mark-dirty if different), which is only a few cycles.
[edit]
Just noticed he mentions something similar as an idea for otimizing. I think my idea is slightly better than his because it can be done with about half as much memory.