|
|
|
@ -12,38 +12,55 @@
|
|
|
|
|
#define MBOX_TAG_FBSETPIXORD 0x48006 |
|
|
|
|
#define MBOX_TAG_FBSETOFF 0x48009 |
|
|
|
|
|
|
|
|
|
unsigned char *init_fb(struct fbst *fb) { |
|
|
|
|
/* PC Screen Font as used by Linux Console */ |
|
|
|
|
typedef struct { |
|
|
|
|
unsigned int magic; |
|
|
|
|
unsigned int version; |
|
|
|
|
unsigned int headersize; |
|
|
|
|
unsigned int flags; |
|
|
|
|
unsigned int numglyph; |
|
|
|
|
unsigned int bytesperglyph; |
|
|
|
|
unsigned int height; |
|
|
|
|
unsigned int width; |
|
|
|
|
unsigned char glyphs; |
|
|
|
|
} __attribute__((packed)) psf_t; |
|
|
|
|
extern volatile unsigned char _binary_font_psf_start; |
|
|
|
|
|
|
|
|
|
static struct fbst fb; |
|
|
|
|
|
|
|
|
|
unsigned char *fb_init() |
|
|
|
|
{ |
|
|
|
|
// sending many tags at once
|
|
|
|
|
mbox[0] = 35 * 4; |
|
|
|
|
mbox[1] = MBOX_REQUEST; |
|
|
|
|
mbox[2] = MBOX_TAG_FBSETPHYS; // set phy wh
|
|
|
|
|
mbox[3] = 8; |
|
|
|
|
mbox[4] = 0; |
|
|
|
|
mbox[5] = 1920; // FrameBufferInfo.width
|
|
|
|
|
mbox[6] = 1080; // FrameBufferInfo.height
|
|
|
|
|
mbox[7] = MBOX_TAG_FBSETVIRT; // set virt wh
|
|
|
|
|
mbox[8] = 8; |
|
|
|
|
mbox[9] = 0; |
|
|
|
|
mbox[10] = 1920; // FrameBufferInfo.virtual_width
|
|
|
|
|
mbox[11] = 1080; // FrameBufferInfo.virtual_height
|
|
|
|
|
mbox[0] = 35 * 4; |
|
|
|
|
mbox[1] = MBOX_REQUEST; |
|
|
|
|
mbox[2] = MBOX_TAG_FBSETPHYS; // set phy wh
|
|
|
|
|
mbox[3] = 8; |
|
|
|
|
mbox[4] = 0; |
|
|
|
|
mbox[5] = 1920; // FrameBufferInfo.width
|
|
|
|
|
mbox[6] = 1080; // FrameBufferInfo.height
|
|
|
|
|
mbox[7] = MBOX_TAG_FBSETVIRT; // set virt wh
|
|
|
|
|
mbox[8] = 8; |
|
|
|
|
mbox[9] = 0; |
|
|
|
|
mbox[10] = 1920; // FrameBufferInfo.virtual_width
|
|
|
|
|
mbox[11] = 1080; // FrameBufferInfo.virtual_height
|
|
|
|
|
mbox[12] = MBOX_TAG_FBSETOFF; // set virt offset
|
|
|
|
|
mbox[13] = 8; |
|
|
|
|
mbox[14] = 0; |
|
|
|
|
mbox[15] = 0; // FrameBufferInfo.x_offset
|
|
|
|
|
mbox[16] = 0; // FrameBufferInfo.y.offset
|
|
|
|
|
mbox[15] = 0; // FrameBufferInfo.x_offset
|
|
|
|
|
mbox[16] = 0; // FrameBufferInfo.y.offset
|
|
|
|
|
mbox[17] = MBOX_TAG_FBSETDEPTH; // set depth
|
|
|
|
|
mbox[18] = 4; |
|
|
|
|
mbox[19] = 0; |
|
|
|
|
mbox[20] = 32; // FrameBufferInfo.depth
|
|
|
|
|
mbox[20] = 32; // FrameBufferInfo.depth
|
|
|
|
|
mbox[21] = MBOX_TAG_FBSETPIXORD; // set pixel order
|
|
|
|
|
mbox[22] = 4; |
|
|
|
|
mbox[23] = 0; |
|
|
|
|
mbox[24] = 1; // RGB, not BGR preferably
|
|
|
|
|
mbox[24] = 1; // RGB, not BGR preferably
|
|
|
|
|
mbox[25] = MBOX_TAG_FBALLOC; // get framebuffer, gets alignment on request
|
|
|
|
|
mbox[26] = 8; |
|
|
|
|
mbox[27] = 0; |
|
|
|
|
mbox[28] = 4096; // FrameBufferInfo.pointer
|
|
|
|
|
mbox[29] = 0; // FrameBufferInfo.size
|
|
|
|
|
mbox[28] = 4096; // FrameBufferInfo.pointer
|
|
|
|
|
mbox[29] = 0; // FrameBufferInfo.size
|
|
|
|
|
mbox[30] = MBOX_TAG_FBGETPITCH; // get pitch
|
|
|
|
|
mbox[31] = 4; |
|
|
|
|
mbox[32] = 0; |
|
|
|
@ -52,15 +69,64 @@ unsigned char *init_fb(struct fbst *fb) {
|
|
|
|
|
|
|
|
|
|
if (mbox_call(MBOX_CH_PROP, mbox) == 0 && mbox[20] == 32 && mbox[28] != 0) { |
|
|
|
|
mbox[28] &= 0x3FFFFFFF; // convert GPU address to ARM address
|
|
|
|
|
fb->width = mbox[5]; // get actual physical width
|
|
|
|
|
fb->height = mbox[6]; // get actual physical height
|
|
|
|
|
fb->pitch = mbox[33]; // get number of bytes per line
|
|
|
|
|
fb->isrgb = mbox[24]; // get the actual channel order
|
|
|
|
|
fb->fbp = (void *)((unsigned long)mbox[28]); |
|
|
|
|
fb.width = mbox[5]; // get actual physical width
|
|
|
|
|
fb.height = mbox[6]; // get actual physical height
|
|
|
|
|
fb.pitch = mbox[33]; // get number of bytes per line
|
|
|
|
|
fb.isrgb = mbox[24]; // get the actual channel order
|
|
|
|
|
fb.fbp = (void *)((unsigned long)mbox[28]); |
|
|
|
|
} else { |
|
|
|
|
puts("Unable to set framebuffer!\r\n"); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return fb->fbp; |
|
|
|
|
return fb.fbp; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct fbst * fb_get(){ |
|
|
|
|
return &fb; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void fb_print(int x, int y, char *s) |
|
|
|
|
{ |
|
|
|
|
// get our font
|
|
|
|
|
psf_t *font = (psf_t *)&_binary_font_psf_start; |
|
|
|
|
// draw next character if it's not zero
|
|
|
|
|
while (*s) { |
|
|
|
|
// get the offset of the glyph. Need to adjust this to support unicode table
|
|
|
|
|
unsigned char *glyph = |
|
|
|
|
(unsigned char *)&_binary_font_psf_start + font->headersize + |
|
|
|
|
(*((unsigned char *)s) < font->numglyph ? *s : 0) * font->bytesperglyph; |
|
|
|
|
// calculate the offset on screen
|
|
|
|
|
int offs = (y * fb.pitch) + (x * 4); |
|
|
|
|
// variables
|
|
|
|
|
int line, mask, bytesperline = (font->width + 7) / 8; |
|
|
|
|
// handle carrige return
|
|
|
|
|
if (*s == '\r') { |
|
|
|
|
x = 0; |
|
|
|
|
} else |
|
|
|
|
// new line
|
|
|
|
|
if (*s == '\n') { |
|
|
|
|
x = 0; |
|
|
|
|
y += font->height; |
|
|
|
|
} else { |
|
|
|
|
// display a character
|
|
|
|
|
for (unsigned int j = 0; j < font->height; j++) { |
|
|
|
|
// display one row
|
|
|
|
|
line = offs; |
|
|
|
|
mask = 1 << (font->width - 1); |
|
|
|
|
for (unsigned int i = 0; i < font->width; i++) { |
|
|
|
|
// if bit set, we use white color, otherwise black
|
|
|
|
|
*((unsigned int *)(fb.fbp + line)) = ((int)*glyph) & mask ? 0xFFFFFF : 0; |
|
|
|
|
mask >>= 1; |
|
|
|
|
line += 4; |
|
|
|
|
} |
|
|
|
|
// adjust to next line
|
|
|
|
|
glyph += bytesperline; |
|
|
|
|
offs += fb.pitch; |
|
|
|
|
} |
|
|
|
|
x += (font->width + 1); |
|
|
|
|
} |
|
|
|
|
// next character
|
|
|
|
|
s++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|