114 lines
2.9 KiB
C
114 lines
2.9 KiB
C
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
#define WBUF_SIZE 32
|
|
|
|
static int fifo_fd;
|
|
|
|
#define VGASIM_CMD_INIT 0x01
|
|
#define VGASIM_CMD_RESET 0x02
|
|
#define VGASIM_CMD_TICK 0x03
|
|
|
|
int vgasim_init(int screen_h, int screen_w, int screen_bpp) {
|
|
int ret;
|
|
ssize_t bytes_written, bytes_written_total;
|
|
ssize_t pkt_size;
|
|
char wbuf[WBUF_SIZE];
|
|
uint16_t *wbuf_ptr;
|
|
printf("dpi: vgasim_init: %d x %d x %d\n", screen_h, screen_w, screen_bpp);
|
|
|
|
ret = open("/tmp/vgasim", O_WRONLY | O_NONBLOCK);
|
|
if (ret == -1) {
|
|
printf("dpi: vgasim_init: failed (%d)\n", errno);
|
|
return 1;
|
|
}
|
|
|
|
fifo_fd = ret;
|
|
|
|
wbuf_ptr = (uint16_t*)wbuf;
|
|
|
|
*wbuf_ptr++ = VGASIM_CMD_INIT;
|
|
*wbuf_ptr++ = (uint16_t)screen_h;
|
|
*wbuf_ptr++ = (uint16_t)screen_w;
|
|
*wbuf_ptr++ = (uint16_t)screen_bpp;
|
|
|
|
pkt_size = 4 * sizeof(uint16_t);
|
|
|
|
bytes_written_total = 0;
|
|
do {
|
|
bytes_written = write(fifo_fd, wbuf + bytes_written_total, pkt_size - bytes_written_total);
|
|
if (bytes_written < 0) {
|
|
printf("dpi: vgasim_init: write error (%d): %s\n", errno, strerror(errno));
|
|
return 2;
|
|
}
|
|
bytes_written_total += bytes_written;
|
|
} while (bytes_written_total < pkt_size);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int vgasim_reset() {
|
|
int ret;
|
|
ssize_t bytes_written, bytes_written_total;
|
|
ssize_t pkt_size;
|
|
char wbuf[WBUF_SIZE];
|
|
uint16_t *wbuf_ptr;
|
|
|
|
printf("dpi: vgasim_reset\n");
|
|
|
|
wbuf_ptr = (uint16_t*)wbuf;
|
|
*wbuf_ptr++ = VGASIM_CMD_RESET;
|
|
pkt_size = sizeof(uint16_t);
|
|
|
|
bytes_written_total = 0;
|
|
do {
|
|
bytes_written = write(fifo_fd, wbuf + bytes_written_total, pkt_size - bytes_written_total);
|
|
if (bytes_written < 0) {
|
|
printf("dpi: vgasim_init: write error (%d): %s\n", errno, strerror(errno));
|
|
return 2;
|
|
}
|
|
bytes_written_total += bytes_written;
|
|
} while (bytes_written_total < pkt_size);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int vgasim_tick(int r, int g, int b, int hsync, int vsync) {
|
|
int ret;
|
|
ssize_t bytes_written, bytes_written_total;
|
|
ssize_t pkt_size;
|
|
char wbuf[WBUF_SIZE];
|
|
uint16_t *wbuf_ptr16;
|
|
uint8_t *wbuf_ptr8;
|
|
|
|
//printf("dpi: vgasim_tick: %X, %X, %X (%s%s)\n", r, g, b, hsync ? "h" : "", vsync ? "v" : "");
|
|
|
|
wbuf_ptr16 = (uint16_t*)wbuf;
|
|
*wbuf_ptr16++ = VGASIM_CMD_TICK;
|
|
wbuf_ptr8 = (uint8_t*)wbuf_ptr16;
|
|
*wbuf_ptr8++ = (uint8_t)r;
|
|
*wbuf_ptr8++ = (uint8_t)g;
|
|
*wbuf_ptr8++ = (uint8_t)b;
|
|
*wbuf_ptr8++ = (uint8_t)((vsync ? 0x02 : 0x00) | (hsync ? 0x01 : 0x00));
|
|
pkt_size = sizeof(uint16_t) + 4 * sizeof(uint8_t);
|
|
|
|
bytes_written_total = 0;
|
|
do {
|
|
bytes_written = write(fifo_fd, wbuf + bytes_written_total, pkt_size - bytes_written_total);
|
|
if (bytes_written < 0) {
|
|
printf("dpi: vgasim_init: write error (%d): %s\n", errno, strerror(errno));
|
|
return 2;
|
|
}
|
|
bytes_written_total += bytes_written;
|
|
} while (bytes_written_total < pkt_size);
|
|
|
|
return 0;
|
|
}
|