/*
|
/*
|
* graph.c -- graphics controller simulation
|
* graph.c -- graphics controller simulation
|
*/
|
*/
|
|
|
|
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <string.h>
|
#include <setjmp.h>
|
#include <setjmp.h>
|
|
|
#include "common.h"
|
#include "common.h"
|
#include "console.h"
|
#include "console.h"
|
#include "error.h"
|
#include "error.h"
|
#include "except.h"
|
#include "except.h"
|
#include "graph.h"
|
#include "graph.h"
|
|
|
|
|
static Bool debug = false;
|
static Bool debug = false;
|
static volatile Bool installed = false;
|
static Bool volatile installed = false;
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
/**************************************************************/
|
/**************************************************************/
|
|
|
/* common definitions, global variables */
|
/* common definitions, global variables */
|
|
|
|
|
#include <pthread.h>
|
#include <pthread.h>
|
#include <unistd.h>
|
#include <unistd.h>
|
#include <time.h>
|
#include <time.h>
|
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
|
|
|
|
#define WINDOW_SIZE_X 640
|
#define WINDOW_SIZE_X 640
|
#define WINDOW_SIZE_Y 480
|
#define WINDOW_SIZE_Y 480
|
#define WINDOW_POS_X 100
|
#define WINDOW_POS_X 100
|
#define WINDOW_POS_Y 100
|
#define WINDOW_POS_Y 100
|
|
|
|
|
#define C2B(c,ch) (((((c) & 0xFF) * ch.scale) >> 8) * ch.factor)
|
#define C2B(c,ch) (((((c) & 0xFF) * ch.scale) >> 8) * ch.factor)
|
#define RGB2PIXEL(r,g,b) (C2B(r, vga.red) | \
|
#define RGB2PIXEL(r,g,b) (0xFF000000 | \
|
|
C2B(r, vga.red) | \
|
C2B(g, vga.green) | \
|
C2B(g, vga.green) | \
|
C2B(b, vga.blue))
|
C2B(b, vga.blue))
|
|
|
|
|
typedef struct {
|
typedef struct {
|
unsigned long scale;
|
unsigned long scale;
|
unsigned long factor;
|
unsigned long factor;
|
} ColorChannel;
|
} ColorChannel;
|
|
|
|
|
typedef struct {
|
typedef struct {
|
int argc;
|
int argc;
|
char **argv;
|
char **argv;
|
Display *display;
|
Display *display;
|
Window win;
|
Window win;
|
GC gc;
|
GC gc;
|
XImage *image;
|
XImage *image;
|
ColorChannel red, green, blue;
|
ColorChannel red, green, blue;
|
XExposeEvent expose;
|
XExposeEvent expose;
|
XClientMessageEvent shutdown;
|
XClientMessageEvent shutdown;
|
} VGA;
|
} VGA;
|
|
|
|
|
static VGA vga;
|
static VGA vga;
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
/* monitor server */
|
/* monitor server */
|
|
|
|
|
static ColorChannel mask2channel(unsigned long mask) {
|
static ColorChannel mask2channel(unsigned long mask) {
|
unsigned long f;
|
unsigned long f;
|
ColorChannel ch;
|
ColorChannel ch;
|
|
|
if (mask == 0) {
|
if (mask == 0) {
|
error("color mask is 0 in mask2channel");
|
error("color mask is 0 in mask2channel");
|
}
|
}
|
for (f = 1; (mask & 1) == 0; f <<= 1) {
|
for (f = 1; (mask & 1) == 0; f <<= 1) {
|
mask >>= 1;
|
mask >>= 1;
|
}
|
}
|
ch.factor = f;
|
ch.factor = f;
|
ch.scale = mask + 1;
|
ch.scale = mask + 1;
|
while ((mask & 1) != 0) {
|
while ((mask & 1) != 0) {
|
mask >>= 1;
|
mask >>= 1;
|
}
|
}
|
if (mask != 0) {
|
if (mask != 0) {
|
error("scattered color mask bits in mask2channel");
|
error("scattered color mask bits in mask2channel");
|
}
|
}
|
return ch;
|
return ch;
|
}
|
}
|
|
|
|
|
static void initMonitor(int argc, char *argv[]) {
|
static void initMonitor(int argc, char *argv[]) {
|
int screenNum;
|
int screenNum;
|
Window rootWin;
|
Window rootWin;
|
XVisualInfo visualTemp;
|
XVisualInfo visualTemp;
|
XVisualInfo *visualInfo;
|
XVisualInfo *visualInfo;
|
int visualCount;
|
int visualCount;
|
int bestMatch;
|
int bestMatch;
|
int bestDepth;
|
int bestDepth;
|
Visual *visual;
|
Visual *visual;
|
int i;
|
int i;
|
unsigned long pixel;
|
unsigned long pixel;
|
int x, y;
|
int x, y;
|
Colormap colormap;
|
Colormap colormap;
|
XSetWindowAttributes attrib;
|
XSetWindowAttributes attrib;
|
XSizeHints *sizeHints;
|
XSizeHints *sizeHints;
|
XWMHints *wmHints;
|
XWMHints *wmHints;
|
XClassHint *classHints;
|
XClassHint *classHints;
|
XTextProperty windowName;
|
XTextProperty windowName;
|
XGCValues gcValues;
|
XGCValues gcValues;
|
|
|
/* connect to X server */
|
/* connect to X server */
|
if (XInitThreads() == 0) {
|
if (XInitThreads() == 0) {
|
error("no thread support for X11");
|
error("no thread support for X11");
|
}
|
}
|
vga.display = XOpenDisplay(NULL);
|
vga.display = XOpenDisplay(NULL);
|
if (vga.display == NULL) {
|
if (vga.display == NULL) {
|
error("cannot connect to X server");
|
error("cannot connect to X server");
|
}
|
}
|
screenNum = DefaultScreen(vga.display);
|
screenNum = DefaultScreen(vga.display);
|
rootWin = RootWindow(vga.display, screenNum);
|
rootWin = RootWindow(vga.display, screenNum);
|
/* find TrueColor visual */
|
/* find TrueColor visual */
|
visualTemp.screen = screenNum;
|
visualTemp.screen = screenNum;
|
visualTemp.class = TrueColor;
|
visualTemp.class = TrueColor;
|
visualInfo = XGetVisualInfo(vga.display,
|
visualInfo = XGetVisualInfo(vga.display,
|
VisualClassMask | VisualScreenMask,
|
VisualClassMask | VisualScreenMask,
|
&visualTemp, &visualCount);
|
&visualTemp, &visualCount);
|
if (visualInfo == NULL || visualCount == 0) {
|
if (visualInfo == NULL || visualCount == 0) {
|
error("no TrueColor visual found");
|
error("no TrueColor visual found");
|
}
|
}
|
bestMatch = 0;
|
bestMatch = 0;
|
bestDepth = visualInfo[0].depth;
|
bestDepth = visualInfo[0].depth;
|
visual = visualInfo[0].visual;
|
visual = visualInfo[0].visual;
|
for (i = 1; i < visualCount; i++) {
|
for (i = 1; i < visualCount; i++) {
|
if (visualInfo[i].depth > bestDepth) {
|
if (visualInfo[i].depth > bestDepth) {
|
bestMatch = i;
|
bestMatch = i;
|
bestDepth = visualInfo[i].depth;
|
bestDepth = visualInfo[i].depth;
|
visual = visualInfo[i].visual;
|
visual = visualInfo[i].visual;
|
}
|
}
|
}
|
}
|
/* build color channels */
|
/* build color channels */
|
vga.red = mask2channel(visualInfo[bestMatch].red_mask);
|
vga.red = mask2channel(visualInfo[bestMatch].red_mask);
|
vga.green = mask2channel(visualInfo[bestMatch].green_mask);
|
vga.green = mask2channel(visualInfo[bestMatch].green_mask);
|
vga.blue = mask2channel(visualInfo[bestMatch].blue_mask);
|
vga.blue = mask2channel(visualInfo[bestMatch].blue_mask);
|
/* create and initialize image */
|
/* create and initialize image */
|
vga.image = XCreateImage(vga.display, visual, bestDepth, ZPixmap,
|
vga.image = XCreateImage(vga.display, visual, bestDepth, ZPixmap,
|
0, NULL, WINDOW_SIZE_X, WINDOW_SIZE_Y, 32, 0);
|
0, NULL, WINDOW_SIZE_X, WINDOW_SIZE_Y, 32, 0);
|
if (vga.image == NULL) {
|
if (vga.image == NULL) {
|
error("cannot allocate image");
|
error("cannot allocate image");
|
}
|
}
|
vga.image->data = malloc(vga.image->height * vga.image->bytes_per_line);
|
vga.image->data = malloc(vga.image->height * vga.image->bytes_per_line);
|
if (vga.image->data == NULL) {
|
if (vga.image->data == NULL) {
|
error("cannot allocate image memory");
|
error("cannot allocate image memory");
|
}
|
}
|
pixel = RGB2PIXEL(0, 0, 0);
|
pixel = RGB2PIXEL(0, 0, 0);
|
for (y = 0; y < WINDOW_SIZE_Y; y++) {
|
for (y = 0; y < WINDOW_SIZE_Y; y++) {
|
for (x = 0; x < WINDOW_SIZE_X; x++) {
|
for (x = 0; x < WINDOW_SIZE_X; x++) {
|
XPutPixel(vga.image, x, y, pixel);
|
XPutPixel(vga.image, x, y, pixel);
|
}
|
}
|
}
|
}
|
/* allocate a colormap */
|
/* allocate a colormap */
|
colormap = XCreateColormap(vga.display, rootWin, visual, AllocNone);
|
colormap = XCreateColormap(vga.display, rootWin, visual, AllocNone);
|
/* create the window */
|
/* create the window */
|
attrib.colormap = colormap;
|
attrib.colormap = colormap;
|
attrib.event_mask = ExposureMask;
|
attrib.event_mask = ExposureMask;
|
attrib.background_pixel = RGB2PIXEL(0, 0, 0);
|
attrib.background_pixel = RGB2PIXEL(0, 0, 0);
|
attrib.border_pixel = RGB2PIXEL(0, 0, 0);
|
attrib.border_pixel = RGB2PIXEL(0, 0, 0);
|
vga.win =
|
vga.win =
|
XCreateWindow(vga.display, rootWin,
|
XCreateWindow(vga.display, rootWin,
|
WINDOW_POS_X, WINDOW_POS_Y,
|
WINDOW_POS_X, WINDOW_POS_Y,
|
WINDOW_SIZE_X, WINDOW_SIZE_Y,
|
WINDOW_SIZE_X, WINDOW_SIZE_Y,
|
0, bestDepth, InputOutput, visual,
|
0, bestDepth, InputOutput, visual,
|
CWEventMask | CWColormap | CWBackPixel | CWBorderPixel,
|
CWEventMask | CWColormap | CWBackPixel | CWBorderPixel,
|
&attrib);
|
&attrib);
|
/* give hints to window manager */
|
/* give hints to window manager */
|
sizeHints = XAllocSizeHints();
|
sizeHints = XAllocSizeHints();
|
wmHints = XAllocWMHints();
|
wmHints = XAllocWMHints();
|
classHints = XAllocClassHint();
|
classHints = XAllocClassHint();
|
if (sizeHints == NULL ||
|
if (sizeHints == NULL ||
|
wmHints == NULL ||
|
wmHints == NULL ||
|
classHints == NULL) {
|
classHints == NULL) {
|
error("hint allocation failed");
|
error("hint allocation failed");
|
}
|
}
|
sizeHints->flags = PMinSize | PMaxSize;
|
sizeHints->flags = PMinSize | PMaxSize;
|
sizeHints->min_width = WINDOW_SIZE_X;
|
sizeHints->min_width = WINDOW_SIZE_X;
|
sizeHints->min_height = WINDOW_SIZE_Y;
|
sizeHints->min_height = WINDOW_SIZE_Y;
|
sizeHints->max_width = WINDOW_SIZE_X;
|
sizeHints->max_width = WINDOW_SIZE_X;
|
sizeHints->max_height = WINDOW_SIZE_Y;
|
sizeHints->max_height = WINDOW_SIZE_Y;
|
wmHints->flags = StateHint | InputHint;
|
wmHints->flags = StateHint | InputHint;
|
wmHints->input = True;
|
wmHints->input = True;
|
wmHints->initial_state = NormalState;
|
wmHints->initial_state = NormalState;
|
classHints->res_name = "ECO32";
|
classHints->res_name = "ECO32";
|
classHints->res_class = "ECO32";
|
classHints->res_class = "ECO32";
|
if (XStringListToTextProperty(&classHints->res_name, 1, &windowName) == 0) {
|
if (XStringListToTextProperty(&classHints->res_name, 1, &windowName) == 0) {
|
error("property allocation failed");
|
error("property allocation failed");
|
}
|
}
|
XSetWMProperties(vga.display, vga.win, &windowName, NULL,
|
XSetWMProperties(vga.display, vga.win, &windowName, NULL,
|
argv, argc, sizeHints, wmHints, classHints);
|
argv, argc, sizeHints, wmHints, classHints);
|
/* create a GC */
|
/* create a GC */
|
vga.gc = XCreateGC(vga.display, vga.win, 0, &gcValues);
|
vga.gc = XCreateGC(vga.display, vga.win, 0, &gcValues);
|
/* finally get the window displayed */
|
/* finally get the window displayed */
|
XMapWindow(vga.display, vga.win);
|
XMapWindow(vga.display, vga.win);
|
/* prepare expose event */
|
/* prepare expose event */
|
vga.expose.type = Expose;
|
vga.expose.type = Expose;
|
vga.expose.display = vga.display;
|
vga.expose.display = vga.display;
|
vga.expose.window = vga.win;
|
vga.expose.window = vga.win;
|
vga.expose.x = 0;
|
vga.expose.x = 0;
|
vga.expose.y = 0;
|
vga.expose.y = 0;
|
vga.expose.width = WINDOW_SIZE_X;
|
vga.expose.width = WINDOW_SIZE_X;
|
vga.expose.height = WINDOW_SIZE_Y;
|
vga.expose.height = WINDOW_SIZE_Y;
|
vga.expose.count = 0;
|
vga.expose.count = 0;
|
/* prepare shutdown event */
|
/* prepare shutdown event */
|
vga.shutdown.type = ClientMessage;
|
vga.shutdown.type = ClientMessage;
|
vga.shutdown.display = vga.display;
|
vga.shutdown.display = vga.display;
|
vga.shutdown.window = vga.win;
|
vga.shutdown.window = vga.win;
|
vga.shutdown.message_type = XA_WM_COMMAND;
|
vga.shutdown.message_type = XA_WM_COMMAND;
|
vga.shutdown.format = 32;
|
vga.shutdown.format = 8;
|
vga.shutdown.data.l[0] = 0xDEADBEEF;
|
|
/* say that the graphics controller is installed */
|
/* say that the graphics controller is installed */
|
XSync(vga.display, False);
|
XSync(vga.display, False);
|
installed = true;
|
installed = true;
|
}
|
}
|
|
|
|
|
static void exitMonitor(void) {
|
static void exitMonitor(void) {
|
XFreeGC(vga.display, vga.gc);
|
XFreeGC(vga.display, vga.gc);
|
XUnmapWindow(vga.display, vga.win);
|
XUnmapWindow(vga.display, vga.win);
|
XDestroyWindow(vga.display, vga.win);
|
XDestroyWindow(vga.display, vga.win);
|
XDestroyImage(vga.image);
|
XDestroyImage(vga.image);
|
XCloseDisplay(vga.display);
|
XCloseDisplay(vga.display);
|
installed = false;
|
installed = false;
|
}
|
}
|
|
|
|
|
static int ioErrorHandler(Display *display) {
|
static int ioErrorHandler(Display *display) {
|
error("connection to monitor window lost");
|
error("connection to monitor window lost");
|
/* never reached */
|
/* never reached */
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
static void *server(void *ignore) {
|
static void *server(void *ignore) {
|
Bool run;
|
Bool run;
|
XEvent event;
|
XEvent event;
|
|
|
initMonitor(vga.argc, vga.argv);
|
initMonitor(vga.argc, vga.argv);
|
XSetIOErrorHandler(ioErrorHandler);
|
XSetIOErrorHandler(ioErrorHandler);
|
run = true;
|
run = true;
|
while (run) {
|
while (run) {
|
XNextEvent(vga.display, &event);
|
XNextEvent(vga.display, &event);
|
switch (event.type) {
|
switch (event.type) {
|
case Expose:
|
case Expose:
|
XPutImage(vga.display, vga.win, vga.gc, vga.image,
|
XPutImage(vga.display, vga.win, vga.gc, vga.image,
|
event.xexpose.x, event.xexpose.y,
|
event.xexpose.x, event.xexpose.y,
|
event.xexpose.x, event.xexpose.y,
|
event.xexpose.x, event.xexpose.y,
|
event.xexpose.width, event.xexpose.height);
|
event.xexpose.width, event.xexpose.height);
|
break;
|
break;
|
case ClientMessage:
|
case ClientMessage:
|
if (event.xclient.message_type == XA_WM_COMMAND &&
|
if (event.xclient.message_type == XA_WM_COMMAND &&
|
event.xclient.format == 32 &&
|
event.xclient.format == 8) {
|
event.xclient.data.l[0] == 0xDEADBEEF) {
|
|
run = false;
|
run = false;
|
}
|
}
|
break;
|
break;
|
default:
|
default:
|
break;
|
break;
|
}
|
}
|
}
|
}
|
exitMonitor();
|
exitMonitor();
|
return NULL;
|
return NULL;
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
/* refresh timer */
|
/* refresh timer */
|
|
|
|
|
static Bool refreshRunning = false;
|
static Bool volatile refreshRunning = false;
|
|
|
|
|
static void *refresh(void *ignore) {
|
static void *refresh(void *ignore) {
|
struct timespec delay;
|
struct timespec delay;
|
|
|
while (refreshRunning) {
|
while (refreshRunning) {
|
XSendEvent(vga.display, vga.win, False, 0, (XEvent *) &vga.expose);
|
XSendEvent(vga.display, vga.win, False, 0, (XEvent *) &vga.expose);
|
XFlush(vga.display);
|
XFlush(vga.display);
|
delay.tv_sec = 0;
|
delay.tv_sec = 0;
|
delay.tv_nsec = 100 * 1000 * 1000;
|
delay.tv_nsec = 100 * 1000 * 1000;
|
nanosleep(&delay, &delay);
|
nanosleep(&delay, &delay);
|
}
|
}
|
return NULL;
|
return NULL;
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
/* server interface */
|
/* server interface */
|
|
|
|
|
static int myArgc = 1;
|
static int myArgc = 1;
|
static char *myArgv[] = {
|
static char *myArgv[] = {
|
"eco32",
|
"eco32",
|
NULL
|
NULL
|
};
|
};
|
|
|
|
static pthread_t monitorThread;
|
|
static pthread_t refreshThread;
|
|
|
static void vgaInit(void) {
|
|
pthread_attr_t attr;
|
|
pthread_t thread;
|
|
|
|
|
static void vgaInit(void) {
|
/* start monitor server in a separate thread */
|
/* start monitor server in a separate thread */
|
vga.argc = myArgc;
|
vga.argc = myArgc;
|
vga.argv = myArgv;
|
vga.argv = myArgv;
|
pthread_attr_init(&attr);
|
if (pthread_create(&monitorThread, NULL, server, NULL) != 0) {
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
if (pthread_create(&thread, &attr, server, NULL) != 0) {
|
|
error("cannot start monitor server");
|
error("cannot start monitor server");
|
}
|
}
|
while (!installed) sleep(1);
|
while (!installed) ;
|
/* start refresh timer in another thread */
|
/* start refresh timer in another thread */
|
refreshRunning = true;
|
refreshRunning = true;
|
pthread_attr_init(&attr);
|
if (pthread_create(&refreshThread, NULL, refresh, NULL) != 0) {
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
if (pthread_create(&thread, &attr, refresh, NULL) != 0) {
|
|
error("cannot start refresh timer");
|
error("cannot start refresh timer");
|
}
|
}
|
}
|
}
|
|
|
|
|
static void vgaExit(void) {
|
static void vgaExit(void) {
|
refreshRunning = false;
|
refreshRunning = false;
|
sleep(1);
|
pthread_join(refreshThread, NULL);
|
XSendEvent(vga.display, vga.win, False, 0, (XEvent *) &vga.shutdown);
|
XSendEvent(vga.display, vga.win, False, 0, (XEvent *) &vga.shutdown);
|
XSync(vga.display, False);
|
XSync(vga.display, False);
|
while (installed) sleep(1);
|
pthread_join(monitorThread, NULL);
|
}
|
}
|
|
|
|
|
static void vgaWrite(int x, int y, int r, int g, int b) {
|
static void vgaWrite(int x, int y, int r, int g, int b) {
|
XPutPixel(vga.image, x, y, RGB2PIXEL(r, g, b));
|
XPutPixel(vga.image, x, y, RGB2PIXEL(r, g, b));
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
#define BACKGROUND 0
|
#define BACKGROUND 0
|
#define FOREGROUND 1
|
#define FOREGROUND 1
|
|
|
|
|
static int colors[2] = {
|
static int colors[2] = {
|
0x007CD4D6, /* background */
|
0x007CD4D6, /* background */
|
0x00000000 /* foreground */
|
0x00000000 /* foreground */
|
};
|
};
|
|
|
|
|
static int splashData[] = {
|
static int splashData[] = {
|
#include "grsplash"
|
#include "grsplash"
|
};
|
};
|
|
|
|
|
static void loadSplashScreen(void) {
|
static void loadSplashScreen(void) {
|
int sum, i;
|
int sum, i;
|
int count;
|
int count;
|
int plane;
|
int plane;
|
int x, y;
|
int x, y;
|
int r, g, b;
|
int r, g, b;
|
|
|
/* check splash data */
|
/* check splash data */
|
sum = 0;
|
sum = 0;
|
for (i = 0; i < sizeof(splashData)/sizeof(splashData[0]); i++) {
|
for (i = 0; i < sizeof(splashData)/sizeof(splashData[0]); i++) {
|
sum += splashData[i];
|
sum += splashData[i];
|
}
|
}
|
if (sum != WINDOW_SIZE_X * WINDOW_SIZE_Y) {
|
if (sum != WINDOW_SIZE_X * WINDOW_SIZE_Y) {
|
return;
|
return;
|
}
|
}
|
/* display splash data */
|
/* display splash data */
|
count = 0;
|
count = 0;
|
plane = FOREGROUND;
|
plane = FOREGROUND;
|
i = 0;
|
i = 0;
|
for (y = 0; y < WINDOW_SIZE_Y; y++) {
|
for (y = 0; y < WINDOW_SIZE_Y; y++) {
|
for (x = 0; x < WINDOW_SIZE_X; x++) {
|
for (x = 0; x < WINDOW_SIZE_X; x++) {
|
while (count == 0) {
|
while (count == 0) {
|
plane = (plane == BACKGROUND ? FOREGROUND : BACKGROUND);
|
plane = (plane == BACKGROUND ? FOREGROUND : BACKGROUND);
|
r = (colors[plane] >> 16) & 0xFF;
|
r = (colors[plane] >> 16) & 0xFF;
|
g = (colors[plane] >> 8) & 0xFF;
|
g = (colors[plane] >> 8) & 0xFF;
|
b = (colors[plane] >> 0) & 0xFF;
|
b = (colors[plane] >> 0) & 0xFF;
|
count = splashData[i++];
|
count = splashData[i++];
|
}
|
}
|
count--;
|
count--;
|
vgaWrite(x, y, r, g, b);
|
vgaWrite(x, y, r, g, b);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
Word graphRead(Word addr) {
|
Word graphRead(Word addr) {
|
Word data;
|
Word data;
|
|
|
if (debug) {
|
if (debug) {
|
cPrintf("\n**** GRAPH READ from 0x%08X", addr);
|
cPrintf("\n**** GRAPH READ from 0x%08X", addr);
|
}
|
}
|
if (!installed) {
|
if (!installed) {
|
throwException(EXC_BUS_TIMEOUT);
|
throwException(EXC_BUS_TIMEOUT);
|
}
|
}
|
if (addr >= WINDOW_SIZE_X * WINDOW_SIZE_Y * 4) {
|
if (addr >= WINDOW_SIZE_X * WINDOW_SIZE_Y * 4) {
|
throwException(EXC_BUS_TIMEOUT);
|
throwException(EXC_BUS_TIMEOUT);
|
}
|
}
|
/* the frame buffer memory yields 0 on every read */
|
/* the frame buffer memory yields 0 on every read */
|
data = 0;
|
data = 0;
|
if (debug) {
|
if (debug) {
|
cPrintf(", data = 0x%08X ****\n", data);
|
cPrintf(", data = 0x%08X ****\n", data);
|
}
|
}
|
return data;
|
return data;
|
}
|
}
|
|
|
|
|
void graphWrite(Word addr, Word data) {
|
void graphWrite(Word addr, Word data) {
|
if (debug) {
|
if (debug) {
|
cPrintf("\n**** GRAPH WRITE to 0x%08X, data = 0x%08X ****\n",
|
cPrintf("\n**** GRAPH WRITE to 0x%08X, data = 0x%08X ****\n",
|
addr, data);
|
addr, data);
|
}
|
}
|
if (!installed) {
|
if (!installed) {
|
throwException(EXC_BUS_TIMEOUT);
|
throwException(EXC_BUS_TIMEOUT);
|
}
|
}
|
if (addr >= WINDOW_SIZE_X * WINDOW_SIZE_Y * 4) {
|
if (addr >= WINDOW_SIZE_X * WINDOW_SIZE_Y * 4) {
|
throwException(EXC_BUS_TIMEOUT);
|
throwException(EXC_BUS_TIMEOUT);
|
}
|
}
|
/* write to frame buffer memory */
|
/* write to frame buffer memory */
|
vgaWrite((addr >> 2) % WINDOW_SIZE_X,
|
vgaWrite((addr >> 2) % WINDOW_SIZE_X,
|
(addr >> 2) / WINDOW_SIZE_X,
|
(addr >> 2) / WINDOW_SIZE_X,
|
(data >> 16) & 0xFF,
|
(data >> 16) & 0xFF,
|
(data >> 8) & 0xFF,
|
(data >> 8) & 0xFF,
|
(data >> 0) & 0xFF);
|
(data >> 0) & 0xFF);
|
}
|
}
|
|
|
|
|
void graphReset(void) {
|
void graphReset(void) {
|
if (!installed) {
|
if (!installed) {
|
return;
|
return;
|
}
|
}
|
cPrintf("Resetting Graphics...\n");
|
cPrintf("Resetting Graphics...\n");
|
loadSplashScreen();
|
loadSplashScreen();
|
}
|
}
|
|
|
|
|
void graphInit(void) {
|
void graphInit(void) {
|
vgaInit();
|
vgaInit();
|
graphReset();
|
graphReset();
|
}
|
}
|
|
|
|
|
void graphExit(void) {
|
void graphExit(void) {
|
if (!installed) {
|
if (!installed) {
|
return;
|
return;
|
}
|
}
|
vgaExit();
|
vgaExit();
|
}
|
}
|
|
|