initial
[fpgammix.git] / workloads / common / serial-io.c
blob3d44021a60e2c44683c05b4171a42679eae2218f
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 x = 0;
10 unsigned long y = 0;
11 static unsigned long cursor_is_on = 0;
13 static void cursor_flip(void) {
14 unsigned char *d = fb + (6*x) / 8 + 13 * W * y;
15 unsigned sh = (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*x) / 8 + 13 * W * 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_putchar(char ch)
60 long long unsigned i;
62 if (ch != '\n') {
63 unsigned char *d = fb + (6*x) / 8 + 13 * W * y;
64 unsigned char *s = font_fixed_6x13 + 16*(unsigned char)ch;
65 unsigned sh = (x * 6) & 7;
66 unsigned mask = ~ (((1 << 6) - 1) >> sh);
67 unsigned char *s_stop = s + 13;
69 for (; s != s_stop; d += W, ++s) {
70 *d = (*s >> sh) | (*d & mask);
71 // *d = *s;
72 // printf("%x\n", p[i]);
74 if (sh > 2) {
75 d = fb + (6*x) / 8 + 13 * W * y + 1;
76 s = font_fixed_6x13 + 16*(unsigned char)ch;
77 sh = 8 - sh;
78 mask = ~ (((1 << 6) - 1) << sh);
80 for (; s != s_stop; d += W, ++s) {
81 *d = (*s << sh) | (*d & mask);
82 // *d = *s;
83 // printf("%x\n", p[i]);
86 ++x;
89 if (x == (640/6) || ch == '\n') {
90 x = 0;
91 ++y;
92 if (y == (480/13)) {
93 --y;
94 for (i = 0; i < (640 / 64) * 13*(480/13 - 1); ++i)
95 ((long *)fb)[i] = ((long *)fb)[i + 13 * (640 / 64)];
96 for (; i < (640 / 64) * 480; ++i)
97 ((long *)fb)[i] = 0;
102 void fb_puts(char *s)
104 while (*s)
105 fb_putchar(*s++);
108 void fb_puthex(int d, unsigned long v)
110 if (d > 1) fb_puthex(d - 1, v >> 4);
111 fb_putchar("0123456789abcdef"[v & 15]);
114 static unsigned long
115 putint_helper(unsigned long d, unsigned long radix)
117 unsigned long k;
118 unsigned long radix10 = radix * 10;
120 if (d >= radix10)
121 d = putint_helper(d, radix10);
123 for (k = 0; k < 10 && d >= radix; ++k)
124 d -= radix;
125 fb_putchar('0' + k);
126 return d;
129 void fb_putint(long d)
131 if (d < 0)
132 fb_putchar('-'), d = -d;
133 putint_helper(d, 1);
137 void fb_clear(void) {
138 unsigned long *p = (unsigned long *)fb;
139 unsigned long *end = p + 4800;
140 set_mmix_fbaddr0(fb);
142 x = y = cursor_is_on = 0;
144 for (; p != end; p += 10)
145 p[9] = p[8] = p[7] = p[6] = p[5] = p[4] = p[3] = p[2] = p[1] = p[0] = 0;
148 void fb_gotoxy(unsigned long _x, unsigned long _y)
150 x = _x, y = _y;
153 void wait(long unsigned ms) {
154 long unsigned start = now();
155 long cycles = 25000 * ms;
157 while (now() - start < cycles)
161 void wait_us(long unsigned us) {
162 long unsigned start = now();
163 long cycles = 25 * us;
165 while (now() - start < cycles)