Skip to content

Instantly share code, notes, and snippets.

@uobikiemukot
Created August 16, 2014 02:07
Show Gist options
  • Save uobikiemukot/813b0df3810dc1f84335 to your computer and use it in GitHub Desktop.
Save uobikiemukot/813b0df3810dc1f84335 to your computer and use it in GitHub Desktop.
yaft: patch for vga16fb
diff --git a/draw.h b/draw.h
index 541688d..8a9b710 100644
--- a/draw.h
+++ b/draw.h
@@ -1,24 +1,11 @@
/* See LICENSE for licence details. */
-static inline void draw_sixel(struct framebuffer *fb, int line, int col, uint8_t *pixmap)
-{
- int h, w, src_offset, dst_offset;
- uint32_t pixel, color = 0;
-
- for (h = 0; h < CELL_HEIGHT; h++) {
- for (w = 0; w < CELL_WIDTH; w++) {
- src_offset = BYTES_PER_PIXEL * (h * CELL_WIDTH + w);
- memcpy(&color, pixmap + src_offset, BYTES_PER_PIXEL);
-
- dst_offset = (line * CELL_HEIGHT + h) * fb->line_length + (col * CELL_WIDTH + w) * fb->bytes_per_pixel;
- pixel = color2pixel(&fb->vinfo, color);
- memcpy(fb->buf + dst_offset, &pixel, fb->bytes_per_pixel);
- }
- }
-}
+enum {
+ VGA16_COLORS = 16,
+};
static inline void draw_line(struct framebuffer *fb, struct terminal *term, int line)
{
- int pos, size, bdf_padding, glyph_width, margin_right;
+ int pos, bdf_padding, glyph_width, margin_right;
int col, w, h;
uint32_t pixel;
struct color_pair_t color_pair;
@@ -31,10 +18,8 @@ static inline void draw_line(struct framebuffer *fb, struct terminal *term, int
cellp = &term->cells[line][col];
/* draw sixel pixmap */
- if (cellp->has_pixmap) {
- draw_sixel(fb, line, col, cellp->pixmap);
- continue;
- }
+ if (cellp->has_pixmap)
+ continue; /* not supported */
/* copy current color_pair (maybe changed) */
color_pair = cellp->color_pair;
@@ -60,14 +45,13 @@ static inline void draw_line(struct framebuffer *fb, struct terminal *term, int
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;
+ /* fb->bytes_per_pixel must be 1 */
+ pos = (line * CELL_HEIGHT + h) * fb->width
+ + (term->width - 1 - margin_right - w);
/* 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];
@@ -77,17 +61,33 @@ static inline void draw_line(struct framebuffer *fb, struct terminal *term, int
}
}
- /* actual display update (bit blit) */
- 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...
- (maybe we can use this by using libdrm) */
- /* TODO: vertical synchronizing */
+ /* actual display update */
+ uint8_t mask[VGA16_COLORS], color;
+ int b, c, src_offset, dst_offset;
+ for (h = 0; h < CELL_HEIGHT; h++) {
+ for (w = 0; w < fb->width; w += BITS_PER_BYTE) {
+ memset(mask, 0, VGA16_COLORS * sizeof(uint8_t));
+ src_offset = (line * CELL_HEIGHT + h) * fb->width + w;
+ dst_offset = (line * CELL_HEIGHT + h) * fb->line_length + w / BITS_PER_BYTE;
+
+ for (b = 0; b < BITS_PER_BYTE; b++) {
+ color = *(fb->buf + src_offset + b) % VGA16_COLORS;
+ fprintf(stderr, "color index:%d\n", color);
+ /* left top pixel is MSBit of first byte */
+ mask[color] |= 0x80 >> b;
+ //mask[color] |= 0x01 << b;
+ }
+ for (c = 0; c < VGA16_COLORS; c++) {
+ fprintf(stderr, "color mask:0x%.2X\n", mask[c]);
+ if (mask[c]) {
+ vga16_set_color(c);
+ vga16_select_mask();
+ vga16_set_mask((int) mask[c]);
+ vga16_rmw(fb->fp + dst_offset);
+ }
+ }
+ }
+ }
term->line_dirty[line] = ((term->mode & MODE_CURSOR) && term->cursor.y == line) ? true: false;
}
diff --git a/fb/linux.h b/fb/linux.h
index 19ea68e..39961cb 100644
--- a/fb/linux.h
+++ b/fb/linux.h
@@ -7,7 +7,6 @@
struct framebuffer {
uint8_t *fp; /* pointer of framebuffer (read only) */
uint8_t *buf; /* copy of framebuffer */
- uint8_t *wall; /* buffer for wallpaper */
int fd; /* file descriptor of framebuffer */
int width, height; /* display resolution */
long screen_size; /* screen data size (byte) */
@@ -17,17 +16,6 @@ struct framebuffer {
struct fb_var_screeninfo vinfo;
};
-/* common functions */
-uint8_t *load_wallpaper(struct framebuffer *fb)
-{
- uint8_t *ptr;
-
- ptr = (uint8_t *) ecalloc(1, fb->screen_size);
- memcpy(ptr, fb->fp, fb->screen_size);
-
- return ptr;
-}
-
/* some functions for Linux framebuffer */
void cmap_create(struct fb_cmap **cmap)
{
@@ -131,7 +119,7 @@ static inline uint32_t color2pixel(struct fb_var_screeninfo *vinfo, uint32_t col
void fb_init(struct framebuffer *fb, uint32_t *color_palette)
{
int i;
- char *path, *env;
+ char *path;
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;
@@ -169,7 +157,19 @@ void fb_init(struct framebuffer *fb, uint32_t *color_palette)
cmap_init(fb, &vinfo);
fb->bytes_per_pixel = 1;
}
- else /* non packed pixel, mono color, grayscale: not implimented */
+ else if (finfo.type == FB_TYPE_VGA_PLANES && finfo.visual == FB_VISUAL_PSEUDOCOLOR) {
+ /* set ega/vga port permission */
+ if (ioperm(0x3C0, 0x20, 1))
+ fatal("ioperm failed");
+
+ vga16_set_enable_sr(0x0F);
+ vga16_set_op(0);
+ vga16_set_mode(0);
+
+ fb->cmap = fb->cmap_org = NULL;
+ fb->bytes_per_pixel = 1; /* bpp of backbuffer */
+ }
+ else
fatal("unsupported framebuffer type");
for (i = 0; i < COLORS; i++) /* init color palette */
@@ -177,13 +177,7 @@ void fb_init(struct framebuffer *fb, uint32_t *color_palette)
fb->fp = (uint8_t *) emmap(0, fb->screen_size, PROT_WRITE | PROT_READ, MAP_SHARED, fb->fd, 0);
fb->buf = (uint8_t *) ecalloc(1, fb->screen_size);
- //fb->wall = (WALLPAPER && fb->bytes_per_pixel > 1) ? load_wallpaper(fb): NULL;
fb->vinfo = vinfo;
-
- if (((env = getenv("YAFT")) != NULL) && (strstr(env, "wall") != NULL))
- fb->wall = load_wallpaper(fb);
- else
- fb->wall = NULL;
}
void fb_die(struct framebuffer *fb)
@@ -194,7 +188,6 @@ void fb_die(struct framebuffer *fb)
cmap_die(fb->cmap_org);
}
free(fb->buf);
- free(fb->wall);
emunmap(fb->fp, fb->screen_size);
eclose(fb->fd);
}
diff --git a/vga16.h b/vga16.h
new file mode 100644
index 0000000..8aa1abd
--- /dev/null
+++ b/vga16.h
@@ -0,0 +1,72 @@
+/* See LICENSE for licence details. */
+#include <sys/io.h>
+
+enum {
+ GRAPHICS_ADDR_REG = 0x3ce, /* Graphics address register. */
+ GRAPHICS_DATA_REG = 0x3cf, /* Graphics data register. */
+};
+
+/* Program the Set/Reset Register for drawing in color COLOR for write
+ mode 0. */
+static inline void vga16_set_color(int c)
+{
+ outb(0, GRAPHICS_ADDR_REG);
+ outb(c, GRAPHICS_DATA_REG);
+}
+
+/* Set the Enable Set/Reset Register. */
+static inline void vga16_set_enable_sr(int mask)
+{
+ outb(1, GRAPHICS_ADDR_REG);
+ outb(mask, GRAPHICS_DATA_REG);
+}
+
+/* Select the Bit Mask Register on the Graphics Controller. */
+static inline void vga16_select_mask(void)
+{
+ outb(8, GRAPHICS_ADDR_REG);
+}
+
+/* Program the Bit Mask Register to affect only the pixels selected in
+ MASK. The Bit Mask Register must already have been selected with
+ select_mask(). */
+static inline void vga16_set_mask(int mask)
+{
+ outb(mask, GRAPHICS_DATA_REG);
+}
+
+/* Set the Data Rotate Register. Bits 0-2 are rotate count, bits 3-4
+ are logical operation(0=NOP, 1=AND, 2=OR, 3=XOR). */
+static inline void vga16_set_op(int op)
+{
+ outb(3, GRAPHICS_ADDR_REG);
+ outb(op, GRAPHICS_DATA_REG);
+}
+
+/* Set the Memory Plane Write Enable register. */
+static inline void vga16_set_write_planes(int mask)
+{
+ outb(2, 0x3c4);
+ outb(mask, 0x3c5);
+}
+
+/* Set the Read Map Select register. */
+static inline void vga16_set_read_plane(int plane)
+{
+ outb(4, GRAPHICS_ADDR_REG);
+ outb(plane, GRAPHICS_DATA_REG);
+}
+
+/* Set the Graphics Mode Register. The write mode is in bits 0-1, the
+ read mode is in bit 3. */
+static inline void vga16_set_mode(int mode)
+{
+ outb(5, GRAPHICS_ADDR_REG);
+ outb(mode, GRAPHICS_DATA_REG);
+}
+
+/* Read-modify-write the specified memory byte. */
+static inline void vga16_rmw(volatile uint8_t *p)
+{
+ *p |= 1;
+}
diff --git a/yaft.c b/yaft.c
index 6068da2..ad21356 100644
--- a/yaft.c
+++ b/yaft.c
@@ -3,17 +3,10 @@
#include "conf.h"
#include "util.h"
-#if defined(__linux__)
- #include "fb/linux.h"
-#elif defined(__FreeBSD__)
- #include "fb/freebsd.h"
-#elif defined(__NetBSD__)
- #include "fb/netbsd.h"
-#elif defined(__OpenBSD__)
- #include "fb/openbsd.h"
-#endif
-
+#include "vga16.h"
+#include "fb/linux.h"
#include "draw.h"
+
#include "terminal.h"
#include "function.h"
#include "osc.h"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment