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);
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
);
19 for (k
= 0; k
< 13; d
+= W
, ++k
) *d
^= 0xFC >> sh
;
22 d
= fb
+ (6*fb_io_x
) / 8 + 13 * W
* fb_io_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_write(char *buf
, int n
)
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
;
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
);
78 // printf("%x\n", p[i]);
81 d
= fb
+ (6*x
) / 8 + 13 * W
* y
+ 1;
82 s
= font_fixed_6x13
+ 16*(unsigned char)ch
;
84 mask
= ~ ((((1 << 6) - 1) << 2) << sh
);
86 for (; s
!= s_stop
; d
+= W
, ++s
) {
87 *d
= (*s
<< sh
) | (*d
& mask
);
89 // printf("%x\n", p[i]);
95 if (x
== (640/6) || ch
== '\n') {
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
)
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
;