initial
[fpgammix.git] / workloads / common / fb-io.c
blob2fd84213a0610bfc1d8922c0846b13c657187b93
1 #include "mmix-iospace.h"
2 #include "fb-io.h"
3 #include "font-fixed-6x13.h"
5 #define W (640 / 8)
7 // As long as we stay in the first segment, we won't have to deal with the crazy segments.
8 static unsigned char *fb = (unsigned char *) (128 * 1024);
9 unsigned long fb_io_x = 0;
10 unsigned long fb_io_y = 0;
11 static unsigned long cursor_is_on = 0;
13 /*static*/ void cursor_flip(void) {
14 unsigned char *d = fb + (6*fb_io_x) / 8 + 13 * W * fb_io_y;
15 unsigned sh = (fb_io_x * 6) & 7;
16 unsigned mask = ~ (((1 << 6) - 1) >> sh);
17 unsigned k;
19 for (k = 0; k < 13; d += W, ++k) *d ^= 0xFC >> sh;
21 if (sh > 2) {
22 d = fb + (6*fb_io_x) / 8 + 13 * W * fb_io_y + 1;
23 sh = 8 - sh;
24 mask = ~ (((1 << 6) - 1) << sh);
26 for (k = 0; k < 13; d += W, ++k) *d ^= 0xFC << sh;
28 cursor_is_on ^= 1;
31 void fb_cursor_off(void) { if (cursor_is_on) cursor_flip(); }
32 void fb_cursor_on(void) { if (!cursor_is_on) cursor_flip(); }
35 * Ways to speed this up:
37 * 0. Use tetra access to the frame buffer to reduce how often we need to
38 * handle to overlapping case. (Octa access are twice as expensive as tetra
39 * thus unlikely a win).
41 * 1. Move the begining of the framebuffer rather than copying it. If
42 * used with a mask such that the framebuffer loops around, we'd never have to
43 * copy, otherwise we'd have to copy whenever we loop around.
45 * 2. Enhance the SRAM controller with smarts [such at some top address
46 * bits pick mode]. Modes we need here are read-modify-write modes,
47 * like
48 * *dest_addr = (*dest_addr & mask_register) | ((wrdata << shift) >> 32)
50 * (It's not hard to imagine a lot of useful *d = COMBINE(*d, *s) operations)
52 * However, shifters in the SRAM controller are expensive and the
53 * whole approach increasingly looses relevance as the number of
54 * bits pr pixel goes up. (The core actually could play tricks at
55 * the byte level by exploring the byte enables, hmm).
58 void fb_write(char *buf, int n)
60 long unsigned i;
61 // Internal versions for speed, can't trust GCC for this
62 long unsigned x = fb_io_x;
63 long unsigned y = fb_io_y;
65 for (; n; ++buf, --n) {
66 long unsigned ch = *(unsigned char *)buf;
68 if (ch != '\n') {
69 unsigned char *d = fb + (6*x) / 8 + 13 * W * y;
70 unsigned char *s = font_fixed_6x13 + 16*ch;
71 unsigned sh = (x * 6) & 7;
72 unsigned mask = ~ ((((1 << 6) - 1) << 2) >> sh);
73 unsigned char *s_stop = s + 13;
75 for (; s != s_stop; d += W, ++s) {
76 *d = (*s >> sh) | (*d & mask);
77 // *d = *s;
78 // printf("%x\n", p[i]);
80 if (sh > 2) {
81 d = fb + (6*x) / 8 + 13 * W * y + 1;
82 s = font_fixed_6x13 + 16*(unsigned char)ch;
83 sh = 8 - sh;
84 mask = ~ ((((1 << 6) - 1) << 2) << sh);
86 for (; s != s_stop; d += W, ++s) {
87 *d = (*s << sh) | (*d & mask);
88 // *d = *s;
89 // printf("%x\n", p[i]);
92 ++x;
95 if (x == (640/6) || ch == '\n') {
96 x = 0;
97 ++y;
98 if (y == (480/13)) {
99 // Scroll up
100 --y;
101 for (i = 0; i < (640 / 64) * 13*(480/13 - 1); ++i)
102 ((long *)fb)[i] = ((long *)fb)[i + 13 * (640 / 64)];
103 for (; i < (640 / 64) * 480; ++i)
104 ((long *)fb)[i] = 0;
109 // Copy back
110 fb_io_x = x;
111 fb_io_y = y;
114 void fb_clear(void) {
115 unsigned long *p = (unsigned long *)fb;
116 unsigned long *end = p + 4800;
118 set_mmix_fbaddr0(fb);
120 fb_io_x = fb_io_y = cursor_is_on = 0;
122 for (; p != end; p += 10)
123 p[9] = p[8] = p[7] = p[6] = p[5] = p[4] = p[3] = p[2] = p[1] = p[0] = 0;
126 void fb_gotoxy(unsigned long _x, unsigned long _y)
128 fb_io_x = _x, fb_io_y = _y;