Skip to content

Instantly share code, notes, and snippets.

@ao-kenji
Last active February 3, 2022 11:35
Show Gist options
  • Save ao-kenji/8169738 to your computer and use it in GitHub Desktop.
Save ao-kenji/8169738 to your computer and use it in GitHub Desktop.
A test program to check the usage of 8bpp frame buffer on OpenBSD/luna88k.
/*
* test program for luna88k 4/8bpp frame buffer
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/types.h>
#include <dev/wscons/wsconsio.h>
#define DEBUG
/*
* Helper macros (Note: the offsets are different from those in lunafb.c)
*/
#define P0(addr) ((u_int32_t *)((u_int8_t *)(addr)))
#define P1(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0x040000))
#define P2(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0x080000))
#define P3(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0x0c0000))
#define P4(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0x100000))
#define P5(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0x140000))
#define P6(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0x180000))
#define P7(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0x1c0000))
#define ALL1BITS 0xffffffff
#define ALL0BITS 0x00000000
#define LINEBYTES 0x100
struct wsdisplay_cmap wsd_cmap, wsd_orig_cmap;
/* prototype */
void putbox(u_int32_t *, u_int32_t);
int set_cmap(int, int);
int restore_cmap(int, int);
int
main(int argc, char **argv)
{
int fd, i, j;
u_int data, depth, gtype, gmode, orig_gmode;
u_int32_t *fbstart, *start, *p;
u_int32_t pat;
struct wsdisplay_fbinfo wsd_fbinfo;
wsd_cmap.red = (u_char *)malloc(sizeof(u_char) * 256);
wsd_cmap.green = (u_char *)malloc(sizeof(u_char) * 256);
wsd_cmap.blue = (u_char *)malloc(sizeof(u_char) * 256);
wsd_orig_cmap.red = (u_char *)malloc(sizeof(u_char) * 256);
wsd_orig_cmap.green = (u_char *)malloc(sizeof(u_char) * 256);
wsd_orig_cmap.blue = (u_char *)malloc(sizeof(u_char) * 256);
fd = open("/dev/ttyC0", O_RDWR, 0666);
if (fd == -1) {
perror("open");
return 1;
}
ioctl(fd, WSDISPLAYIO_GTYPE, &gtype);
printf("GTYPE: %d,\t", gtype);
ioctl(fd, WSDISPLAYIO_GMODE, &orig_gmode);
printf("GMODE: %d,\t", orig_gmode);
gmode = WSDISPLAYIO_MODE_DUMBFB;
if (ioctl(fd, WSDISPLAYIO_SMODE, &gmode) == -1) {
perror("ioctl:WSDISPLAYIO_SMODE");
close(fd);
return 1;
}
/* get frame buffer depth */
ioctl(fd, WSDISPLAYIO_GINFO, &wsd_fbinfo);
printf("WSDISPLAYIO_GINFO: %d %d %d %d\n",
wsd_fbinfo.height, wsd_fbinfo.width,
wsd_fbinfo.depth, wsd_fbinfo.cmsize);
depth = wsd_fbinfo.depth;
if ((depth != 1) && (depth != 4) && (depth != 8)) {
printf("depth = %d, not one of 1/4/8, exit...\n");
goto exit;
}
if (set_cmap(fd, depth) == -1)
goto exit;
fbstart = mmap(NULL, 0x40000 * depth, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if (fbstart == MAP_FAILED) {
perror("mmap");
goto exit;
}
/* LUNA's frame buffer srarts with 64 bits(8 bytes) offset */
fbstart = fbstart + (64 / 32);
/* offset for this test program, start at x=64, y=64) */
fbstart = fbstart + (64 / 32) + (LINEBYTES / 4 * 64);
p = start = fbstart;
for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j++) {
int color = i * 16 + j;
pat = color & 0x01 ? ALL1BITS : ALL0BITS ;
putbox(P0(p), pat);
if ((depth == 4) || (depth == 8)) {
pat = color & 0x02 ? ALL1BITS : ALL0BITS ;
putbox(P1(p), pat);
pat = color & 0x04 ? ALL1BITS : ALL0BITS ;
putbox(P2(p), pat);
pat = color & 0x08 ? ALL1BITS : ALL0BITS ;
putbox(P3(p), pat);
}
if (depth == 8) {
pat = color & 0x10 ? ALL1BITS : ALL0BITS ;
putbox(P4(p), pat);
pat = color & 0x20 ? ALL1BITS : ALL0BITS ;
putbox(P5(p), pat);
pat = color & 0x40 ? ALL1BITS : ALL0BITS ;
putbox(P6(p), pat);
pat = color & 0x80 ? ALL1BITS : ALL0BITS ;
putbox(P7(p), pat);
}
p++; /* go to next 4 byte */
}
start += (LINEBYTES / 4 * 32); /* go down to 32 lines */
p = start;
}
munmap(fbstart, 0x40000 * depth);
/* wait a key, to see the results */
getchar();
restore_cmap(fd, depth);
exit:
ioctl(fd, WSDISPLAYIO_SMODE, &orig_gmode);
close(fd);
return 0;
}
/*
* put a 32x32 aligned box
*/
void
putbox(u_int32_t *addr, u_int32_t pat)
{
int i;
u_int32_t *dst = addr;
for (i = 0; i < 32; i++) {
*dst = pat;
dst += (LINEBYTES / 4); /* go down one line */
}
}
/*
* set colormap
*/
int
set_cmap(int fd, int depth) {
int count = 0, i, j, k, ret;
if (depth == 1)
return 0;
wsd_orig_cmap.index = 0;
wsd_orig_cmap.count = 1 << depth;
ret = ioctl(fd, WSDISPLAYIO_GETCMAP, &wsd_orig_cmap);
if (ret == -1)
printf("WSDISPLAY_GETCMAP error\n");
/* make our colormap */
/* the first 16 colors are ANSI colors, copied from original */
for (i = 0; i < 16; i++) {
#if 1
wsd_cmap.red[count] = wsd_orig_cmap.red[count];
wsd_cmap.green[count] = wsd_orig_cmap.green[count];
wsd_cmap.blue[count] = wsd_orig_cmap.blue[count];
#else
/* test for gray scale */
wsd_cmap.red[count] = i * 10;
wsd_cmap.green[count] = i * 10;
wsd_cmap.blue[count] = i * 10;
#endif
count++;
}
/* the next 6 x 6 x 6 = 216 colors are from color cube */
for (i = 0; i < 6; i++) {
for (j = 0; j < 6; j++) {
for (k = 0; k < 6; k++) {
wsd_cmap.red[count] = 0x33 * i;
wsd_cmap.green[count] = 0x33 * j;
wsd_cmap.blue[count] = 0x33 * k;
count++;
}
}
}
/* the last 24 colors are gray scale colors */
for (i = 1; i <= 24; i++) {
wsd_cmap.red[count] = 10 * i;
wsd_cmap.green[count] = 10 * i;
wsd_cmap.blue[count] = 10 * i;
count++;
}
/* put our colormap */
wsd_cmap.index = 0;
wsd_cmap.count = 1 << depth;
ret = ioctl(fd, WSDISPLAYIO_PUTCMAP, &wsd_cmap);
if (ret == -1)
printf("WSDISPLAY_PUTCMAP error\n");
return ret;
}
/*
* restore original colormap
*/
int
restore_cmap(int fd, int depth) {
int ret;
if (depth == 1)
return 0;
wsd_orig_cmap.index = 0;
wsd_orig_cmap.count = 1 << depth;
ret = ioctl(fd, WSDISPLAYIO_PUTCMAP, &wsd_orig_cmap);
if (ret == -1)
printf("WSDISPLAY_PUTCMAP error\n");
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment