Starting work on PPU -> display -> VGA
This commit is contained in:
113
dpi/vgasim.c
Normal file
113
dpi/vgasim.c
Normal file
@@ -0,0 +1,113 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user