Skip to content

Instantly share code, notes, and snippets.

@ao-kenji
Created August 9, 2014 21:26
Show Gist options
  • Save ao-kenji/4e95dfe2cf5033c902d9 to your computer and use it in GitHub Desktop.
Save ao-kenji/4e95dfe2cf5033c902d9 to your computer and use it in GitHub Desktop.
yaft ( http://uobikiemukot.github.io/yaft/ ) on OpenBSD/luna88k, take 1. 1bpp version.
diff --git a/conf.h b/conf.h
index 3aade0c..34d7f59 100644
--- a/conf.h
+++ b/conf.h
@@ -2,10 +2,17 @@
/* color: index number of color_palette[] (see color.h) */
enum {
+#if 0
DEFAULT_FG = 7,
DEFAULT_BG = 0,
ACTIVE_CURSOR_COLOR = 2,
PASSIVE_CURSOR_COLOR = 1,
+#else
+ DEFAULT_FG = 8,
+ DEFAULT_BG = 0,
+ ACTIVE_CURSOR_COLOR = 8,
+ PASSIVE_CURSOR_COLOR = 1,
+#endif
};
/* misc */
diff --git a/draw.h b/draw.h
index 9871ba3..b2c26c0 100644
--- a/draw.h
+++ b/draw.h
@@ -1,6 +1,8 @@
/* See LICENSE for licence details. */
static inline void draw_sixel(struct framebuffer *fb, int line, int col, uint8_t *bitmap)
{
+ /* XXX: Maybe need to re-write on LUNA */
+
int h, w, src_offset, dst_offset;
uint32_t pixel, color = 0;
@@ -16,16 +18,29 @@ static inline void draw_sixel(struct framebuffer *fb, int line, int col, uint8_t
}
}
+/* Based on OpenBSD:src/sys/arch/luna88k/dev/omrasops.c */
+
+#define ALL1BITS (~0U)
+#define ALL0BITS (0U)
+#define BLITWIDTH (32)
+#define ALIGNMASK (0x1f)
+#define BYTESDONE (4)
+#define NBBY (8)
+#define W(addr) ((u_int32_t *)(addr))
+#define R(addr) ((u_int32_t *)(addr))
+
static inline void draw_line(struct framebuffer *fb, struct terminal *term, int line)
{
- int pos, size, bdf_padding, glyph_width, margin_right;
- int col, w, h;
- uint32_t pixel;
+ int pos, size, bdf_padding, glyph_width;
+ int col;
struct color_pair_t color_pair;
struct cell_t *cellp;
+ u_int8_t *p;
+ int x, y, width, height, align;
+ u_int32_t lmask, rmask, glyph, inverse;
+
for (col = term->cols - 1; col >= 0; col--) {
- margin_right = (term->cols - 1 - col) * CELL_WIDTH;
/* target cell */
cellp = &term->cells[col + line * term->cols];
@@ -39,11 +54,16 @@ static inline void draw_line(struct framebuffer *fb, struct terminal *term, int
/* copy current color_pair (maybe changed) */
color_pair = cellp->color_pair;
+#if 0
/* check wide character or not */
glyph_width = (cellp->width == HALF) ? CELL_WIDTH: CELL_WIDTH * 2;
bdf_padding = my_ceil(glyph_width, BITS_PER_BYTE) * BITS_PER_BYTE - glyph_width;
if (cellp->width == WIDE)
bdf_padding += CELL_WIDTH;
+#endif
+ /* check wide character or not */
+ if (cellp->width == NEXT_TO_WIDE)
+ continue;
/* check cursor positon */
if ((term->mode & MODE_CURSOR && line == term->cursor.y)
@@ -54,40 +74,64 @@ static inline void draw_line(struct framebuffer *fb, struct terminal *term, int
color_pair.bg = (!tty.visible && BACKGROUND_DRAW) ? PASSIVE_CURSOR_COLOR: ACTIVE_CURSOR_COLOR;
}
- for (h = 0; h < CELL_HEIGHT; h++) {
- /* if UNDERLINE attribute on, swap bg/fg */
- if ((h == (CELL_HEIGHT - 1)) && (cellp->attribute & attr_mask[ATTR_UNDERLINE]))
- color_pair.bg = color_pair.fg;
-
- for (w = 0; w < CELL_WIDTH; w++) {
- pos = (term->width - 1 - margin_right - w) * fb->bytes_per_pixel
- + (line * CELL_HEIGHT + h) * fb->line_length;
-
- /* set color palette */
- if (cellp->glyphp->bitmap[h] & (0x01 << (bdf_padding + w)))
- pixel = term->color_palette[color_pair.fg];
- else if (fb->wall && color_pair.bg == DEFAULT_BG) /* wallpaper */
- memcpy(&pixel, fb->wall + pos, fb->bytes_per_pixel);
- else
- pixel = term->color_palette[color_pair.bg];
-
- /* update copy buffer only */
- memcpy(fb->buf + pos, &pixel, fb->bytes_per_pixel);
+ /* XXX: UNDERLINE */
+
+ x = CELL_WIDTH * col;
+ y = CELL_HEIGHT * line;
+ inverse = ALL0BITS;
+
+ p = (u_int8_t *)fb->buf + y * fb->line_length + ((x / 32) * 4);
+ align = x & ALIGNMASK;
+ width = cellp->width * CELL_WIDTH + align;
+ lmask = ALL1BITS >> align;
+ rmask = ALL1BITS << (-width & ALIGNMASK);
+ height = 0;
+
+ if (width <= BLITWIDTH) {
+ lmask &= rmask;
+ while (height < CELL_HEIGHT) {
+ glyph = (uint32_t)cellp->glyphp->bitmap[height];
+ /* shift leftmost */
+ glyph <<= (4 - cellp->width) * NBBY;
+ glyph = (glyph >> align) ^ inverse;
+ *W(p) = (*R(p) & ~lmask) | (glyph & lmask);
+ p += fb->line_length;
+ height++;
+ }
+ } else {
+ u_int8_t *q = p;
+ u_int32_t lhalf, rhalf;
+ while (height < CELL_HEIGHT) {
+ glyph = (uint32_t)cellp->glyphp->bitmap[height];
+ /* shift leftmost */
+ glyph <<= (4 - cellp->width) * NBBY;
+
+ lhalf = (glyph >> align) ^ inverse;
+ *W(p) = (*R(p) & ~lmask) | (lhalf & lmask);
+
+ p += BYTESDONE;
+
+ rhalf = (glyph << (BLITWIDTH - align)) ^ inverse;
+ *W(p) = (rhalf & rmask) | (*R(p) & ~rmask);
+
+ p = (q += fb->line_length);
+ height++;
}
}
}
/* actual display update (bit blit) */
+#if 0
pos = (line * CELL_HEIGHT) * fb->line_length;
size = CELL_HEIGHT * fb->line_length;
memcpy(fb->fp + pos, fb->buf + pos, size);
-
- /* TODO: page flip
- if fb_fix_screeninfo.ypanstep > 0, we can use hardware panning.
- set fb_fix_screeninfo.{yres_virtual,yoffset} and call ioctl(FBIOPAN_DISPLAY)
- but drivers of recent hardware (inteldrmfb, nouveaufb, radeonfb) don't support...
- (we can use this by using libdrm)
- */
+#else
+ for (height = 0; height < CELL_HEIGHT; height++) {
+ pos = (line * CELL_HEIGHT + height) * fb->line_length;
+ size = TERM_WIDTH / 8;
+ memcpy(fb->fp + pos, fb->buf + pos, size);
+ }
+#endif
term->line_dirty[line] = ((term->mode & MODE_CURSOR) && term->cursor.y == line) ? true: false;
}
diff --git a/fb/openbsd.h b/fb/openbsd.h
index 5a11596..d16632a 100644
--- a/fb/openbsd.h
+++ b/fb/openbsd.h
@@ -13,11 +13,17 @@ typedef unsigned long u_long;
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsksymdef.h>
-/* some structs for NetBSD */
+/* some structs for OpenBSD */
enum term_size {
+#if 0
TERM_WIDTH = 640,
TERM_HEIGHT = 480,
DEPTH = 8,
+#else
+ TERM_WIDTH = 1280,
+ TERM_HEIGHT = 1024,
+ DEPTH = 1,
+#endif
};
enum fbtype_t {
@@ -45,6 +51,7 @@ struct fbinfo_t {
struct framebuffer {
uint8_t *fp; /* pointer of framebuffer(read only) */
+ uint8_t *fp_orig; /* pointer of framebuffer(original) */
uint8_t *wall; /* buffer for wallpaper */
uint8_t *buf; /* copy of framebuffer */
int fd; /* file descriptor of framebuffer */
@@ -83,7 +90,7 @@ uint8_t *load_wallpaper(struct framebuffer *fb)
return ptr;
}
-/* some functions for NetBSD framebuffer */
+/* some functions for OpenBSD framebuffer */
void cmap_create(struct wsdisplay_cmap **cmap, int size)
{
*cmap = (struct wsdisplay_cmap *) ecalloc(1, sizeof(struct wsdisplay_cmap));
@@ -197,12 +204,19 @@ void fb_init(struct framebuffer *fb, uint32_t *color_palette)
goto fb_init_error;
}
+ /* XXX: Should be check if WSDISPLAYIO_TYPE_LUNA ? */
+
fb->width = TERM_WIDTH;
fb->height = TERM_HEIGHT;
fb->bytes_per_pixel = my_ceil(DEPTH, BITS_PER_BYTE);
+#if 0
fb->line_length = fb->bytes_per_pixel * fb->width;
fb->screen_size = fb->height * fb->line_length;
+#else
+ fb->line_length = 2048 / 8;
+ fb->screen_size = fb->height * fb->line_length * DEPTH;
+#endif
fb->vinfo = bpp_table[DEPTH];
if (DEBUG)
@@ -214,7 +228,7 @@ void fb_init(struct framebuffer *fb, uint32_t *color_palette)
fb->cmap = fb->cmap_org = NULL;
fb->vinfo.fbtype = FBTYPE_RGB;
}
- else if (DEPTH == 8) {
+ else if (DEPTH == 8 || DEPTH == 4 || DEPTH == 1 ) {
cmap_create(&fb->cmap, COLORS);
cmap_create(&fb->cmap_org, finfo.cmsize);
cmap_init(fb);
@@ -226,7 +240,10 @@ void fb_init(struct framebuffer *fb, uint32_t *color_palette)
for (i = 0; i < COLORS; i++) /* init color palette */
color_palette[i] = (fb->bytes_per_pixel == 1) ? (uint32_t) i: color2pixel(&fb->vinfo, color_list[i]);
- fb->fp = (uint8_t *) emmap(0, fb->screen_size, PROT_WRITE | PROT_READ, MAP_SHARED, fb->fd, 0);
+ fb->fp_orig = (uint8_t *) emmap(0, fb->screen_size + 0x4000, PROT_WRITE | PROT_READ, MAP_SHARED, fb->fd, 0);
+
+ fb->fp = fb->fp_orig + 8; /* XXX: LUNA quirk; need 8 byte offset */
+
fb->buf = (uint8_t *) ecalloc(1, fb->screen_size);
//fb->wall = (WALLPAPER && fb->bytes_per_pixel > 1) ? load_wallpaper(fb): NULL;
@@ -251,6 +268,6 @@ void fb_die(struct framebuffer *fb)
}
free(fb->buf);
free(fb->wall);
- emunmap(fb->fp, fb->screen_size);
+ emunmap(fb->fp_orig, fb->screen_size);
eclose(fb->fd);
}
diff --git a/makefile b/makefile
index caf405f..8fc5679 100644
--- a/makefile
+++ b/makefile
@@ -1,7 +1,8 @@
CC ?= gcc
#CC ?= clang
-CFLAGS ?= -std=c99 -pedantic -Wall -Wextra -O3 -s -pipe
+#CFLAGS ?= -std=c99 -pedantic -Wall -Wextra -O3 -s -pipe
+CFLAGS = -std=c99 -pedantic -Wall -Wextra -O3 -s -pipe
LDFLAGS ?=
XCFLAGS ?= -std=c99 -pedantic -Wall -Wextra -I/usr/include/X11/ -O3 -s -pipe
diff --git a/yaft.c b/yaft.c
index 9acbad6..cbeaf9f 100644
--- a/yaft.c
+++ b/yaft.c
@@ -77,11 +77,13 @@ void tty_init(struct termios *save_tm)
vtm.mode = VT_PROCESS;
vtm.waitv = 0;
vtm.relsig = vtm.acqsig = vtm.frsig = SIGUSR1;
+#if 0
if (ioctl(STDIN_FILENO, VT_SETMODE, &vtm))
fatal("ioctl: VT_SETMODE failed (maybe here is not console)");
if (ioctl(STDIN_FILENO, KDSETMODE, KD_GRAPHICS))
fatal("ioctl: KDSETMODE failed (maybe here is not console)");
+#endif
etcgetattr(STDIN_FILENO, save_tm);
set_rawmode(STDIN_FILENO, save_tm);
@@ -102,8 +104,10 @@ void tty_die(struct termios *save_tm)
vtm.mode = VT_AUTO;
vtm.waitv = 0;
vtm.relsig = vtm.acqsig = vtm.frsig = 0;
+#if 0
ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
ioctl(STDIN_FILENO, KDSETMODE, KD_TEXT);
+#endif
tcsetattr(STDIN_FILENO, TCSAFLUSH, save_tm);
fflush(stdout);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment