212 lines
5.1 KiB
C++
212 lines
5.1 KiB
C++
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <reent.h>
|
|
#include <errno.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
|
|
#undef errno
|
|
extern int errno;
|
|
|
|
#include "asm.h"
|
|
#include "processor.h"
|
|
#include "color.h"
|
|
|
|
#define FONT_XSIZE 8
|
|
#define FONT_YSIZE 16
|
|
#define FONT_XFACTOR 1
|
|
#define FONT_YFACTOR 1
|
|
#define FONT_XGAP 2
|
|
#define FONT_YGAP 0
|
|
|
|
typedef struct _display_data_s {
|
|
u8 *framebuffer;
|
|
u8 *font;
|
|
int xres,yres,stride;
|
|
int cursor_x,cursor_y;
|
|
int border_left,border_right,border_top,border_bottom;
|
|
int scrolled_lines;
|
|
|
|
unsigned int foreground,background;
|
|
} display_data_s;
|
|
|
|
int displ_open(struct _reent *r, const char *path, int flags,int mode);
|
|
int displ_write(struct _reent *r, int fd, const char *ptr, int len);
|
|
|
|
static struct _display_data_s dsp_displ;
|
|
static struct _display_data_s *displ = &dsp_displ;
|
|
extern u8 display_font_8x16[];
|
|
|
|
|
|
static void __display_drawc(int xpos, int ypos, int c)
|
|
{
|
|
xpos >>= 1;
|
|
int ax, ay;
|
|
unsigned int *ptr = (unsigned int*)(displ->framebuffer + displ->stride * ypos + xpos * 4);
|
|
for (ay = 0; ay < FONT_YSIZE; ay++)
|
|
#if FONT_XFACTOR == 2
|
|
for (ax = 0; ax < 8; ax++)
|
|
{
|
|
unsigned int color;
|
|
if ((displ->font[c * FONT_YSIZE + ay] << ax) & 0x80)
|
|
color = displ->foreground;
|
|
else
|
|
color = displ->background;
|
|
#if FONT_YFACTOR == 2
|
|
// pixel doubling: we write u32
|
|
ptr[ay * 2 * displ->stride/4 + ax] = color;
|
|
// line doubling
|
|
ptr[(ay * 2 +1) * displ->stride/4 + ax] = color;
|
|
#else
|
|
ptr[ay * displ->stride/4 + ax] = color;
|
|
#endif
|
|
}
|
|
#else
|
|
for (ax = 0; ax < 4; ax ++)
|
|
{
|
|
unsigned int color[2];
|
|
int bits = (displ->font[c * FONT_YSIZE + ay] << (ax*2));
|
|
if (bits & 0x80)
|
|
color[0] = displ->foreground;
|
|
else
|
|
color[0] = displ->background;
|
|
if (bits & 0x40)
|
|
color[1] = displ->foreground;
|
|
else
|
|
color[1] = displ->background;
|
|
ptr[ay * displ->stride/4 + ax] = (color[0] & 0xFFFF00FF) | (color[1] & 0x0000FF00);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void ds_init(void *framebuffer,int xstart,int ystart,int xres,int yres,int stride)
|
|
{
|
|
unsigned int level;
|
|
|
|
_CPU_ISR_Disable(level);
|
|
|
|
displ->framebuffer = (u8 *)framebuffer;
|
|
displ->xres = xres;
|
|
displ->yres = yres;
|
|
displ->border_left = xstart;
|
|
displ->border_top = ystart;
|
|
displ->border_right = displ->xres;
|
|
displ->border_bottom = displ->yres;
|
|
displ->stride = stride;
|
|
displ->cursor_x = xstart;
|
|
displ->cursor_y = ystart;
|
|
|
|
displ->font = display_font_8x16;
|
|
|
|
displ->foreground = COLOR_WHITE;
|
|
displ->background = COLOR_BLACK;
|
|
|
|
displ->scrolled_lines = 0;
|
|
|
|
unsigned int c = (displ->xres*displ->yres)/2;
|
|
unsigned int *p = (unsigned int*)displ->framebuffer;
|
|
while(c--)
|
|
*p++ = displ->background;
|
|
|
|
_CPU_ISR_Restore(level);
|
|
}
|
|
|
|
void ds_clear(void)
|
|
{
|
|
unsigned int c = (displ->xres*displ->yres)/2;
|
|
unsigned int *p = (unsigned int*)displ->framebuffer;
|
|
c /= 2;
|
|
p += c;
|
|
while(c--)
|
|
*p++ = displ->background;
|
|
}
|
|
|
|
int display_putc(int c)
|
|
{
|
|
if(!displ) return -1;
|
|
|
|
switch(c)
|
|
{
|
|
case '\n':
|
|
displ->cursor_y += FONT_YSIZE*FONT_YFACTOR+FONT_YGAP;
|
|
displ->cursor_x = displ->border_left;
|
|
break;
|
|
default:
|
|
__display_drawc(displ->cursor_x,displ->cursor_y,c);
|
|
displ->cursor_x += FONT_XSIZE*FONT_XFACTOR+FONT_XGAP;
|
|
if((displ->cursor_x+FONT_XSIZE*FONT_XFACTOR)>displ->border_right) {
|
|
displ->cursor_y += FONT_YSIZE*FONT_YFACTOR+FONT_YGAP;
|
|
displ->cursor_x = displ->border_left;
|
|
}
|
|
}
|
|
|
|
if((displ->cursor_y+FONT_YSIZE*FONT_YFACTOR)>=displ->border_bottom) {
|
|
memcpy(displ->framebuffer,
|
|
displ->framebuffer+displ->stride*(FONT_YSIZE*FONT_YFACTOR+FONT_YGAP),
|
|
displ->stride*displ->yres-FONT_YSIZE);
|
|
|
|
unsigned int cnt = (displ->stride * (FONT_YSIZE * FONT_YFACTOR + FONT_YGAP))/4;
|
|
unsigned int *ptr = (unsigned int*)(displ->framebuffer + displ->stride * (displ->yres - FONT_YSIZE));
|
|
while(cnt--)
|
|
*ptr++ = displ->background;
|
|
displ->cursor_y -= FONT_YSIZE * FONT_YFACTOR + FONT_YGAP;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int displ_write(struct _reent *r,int fd, const char *ptr,int len)
|
|
{
|
|
int i, count = 0;
|
|
char *tmp = (char*)ptr;
|
|
|
|
if(!tmp || len<=0) return -1;
|
|
|
|
i = 0;
|
|
while(*tmp!='\0' && i<len) {
|
|
count += display_putc(*tmp++);
|
|
i++;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
void ds_text_out(int xpos, int ypos, const char *str)
|
|
{
|
|
ypos *= (FONT_YSIZE * FONT_YFACTOR + FONT_YGAP);
|
|
xpos *= (FONT_XSIZE * FONT_XFACTOR + FONT_XGAP);
|
|
while(*str != '\0')
|
|
{
|
|
__display_drawc(xpos, ypos, *str++);
|
|
xpos += (FONT_XSIZE * FONT_XFACTOR + FONT_XGAP);
|
|
};
|
|
}
|
|
|
|
void ds_printf(int x, int y, const char *fmt, ...)
|
|
{
|
|
char tmpbuf[255];
|
|
va_list marker;
|
|
va_start(marker,fmt);
|
|
vsprintf(tmpbuf, fmt, marker );
|
|
va_end(marker);
|
|
ds_text_out(x, y, tmpbuf);
|
|
|
|
}
|
|
|
|
void ds_set_colour(int f, int b)
|
|
{
|
|
displ->background = b;
|
|
displ->foreground = f;
|
|
}
|
|
void ds_underline(int xpos, int ypos, int len, int col)
|
|
{
|
|
int i;
|
|
ypos = (ypos + 1) * (FONT_YSIZE * FONT_YFACTOR + FONT_YGAP) - 1;
|
|
xpos *= (FONT_XSIZE * FONT_XFACTOR + FONT_XGAP)/2;
|
|
len *= (FONT_XSIZE * FONT_XFACTOR + FONT_XGAP)/2;
|
|
unsigned int *ptr = (unsigned int*)(displ->framebuffer + displ->stride * ypos + xpos * 4);
|
|
for(i=0 ; i < len ; i++)
|
|
ptr[i] = col;
|
|
}
|
|
|