1 #include "mmix-iospace.h"
3 #include "font-fixed-6x13.h"
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);
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
);
19 for (k
= 0; k
< 13; d
+= W
, ++k
) *d
^= 0xFC >> sh
;
22 d
= fb
+ (6*x
) / 8 + 13 * W
* y
+ 1;
24 mask
= ~ (((1 << 6) - 1) << sh
);
26 for (k
= 0; k
< 13; d
+= W
, ++k
) *d
^= 0xFC << sh
;
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,
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
)
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
);
72 // printf("%x\n", p[i]);
75 d
= fb
+ (6*x
) / 8 + 13 * W
* y
+ 1;
76 s
= font_fixed_6x13
+ 16*(unsigned char)ch
;
78 mask
= ~ (((1 << 6) - 1) << sh
);
80 for (; s
!= s_stop
; d
+= W
, ++s
) {
81 *d
= (*s
<< sh
) | (*d
& mask
);
83 // printf("%x\n", p[i]);
89 if (x
== (640/6) || ch
== '\n') {
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
)
102 void fb_puts(char *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]);
115 putint_helper(unsigned long d
, unsigned long radix
)
118 unsigned long radix10
= radix
* 10;
121 d
= putint_helper(d
, radix10
);
123 for (k
= 0; k
< 10 && d
>= radix
; ++k
)
129 void fb_putint(long d
)
132 fb_putchar('-'), d
= -d
;
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
)
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
)