1
0
Files
2022-09-29 17:59:04 +03:00

331 lines
6.0 KiB
C

#ident "lib/libsk/graphics/gfx.c: $Revision: 1.148 $"
#include <sys/errno.h>
#include <sys/types.h>
#include <setjmp.h>
#include "saio.h"
#include "saioctl.h"
#include <arcs/hinv.h>
#include "stand_htport.h"
#include "standcfg.h"
#include <gfxgui.h>
#include <ctype.h>
#include <libsc.h>
#include <libsk.h>
#ifdef SN0
#include <sys/SN/SN0/ip27config.h>
#endif /* SN0 */
#define GFX_ENV_VAR "gfx"
#define GFX_OK "alive"
#define GFX_DEAD "dead"
static int gfxISopen;
int gfxalive;
#if defined(IP22) || defined(IP28) || defined(IP30)
int _mgras_run_ide = 0;
#endif
static int _gfxReopen(IOBLOCK *, int );
extern struct htp_state *htp;
#if IPXX || IP22 || IP24 || IP26 || IP28 || IP30
#define MULTIHEAD
#endif
int gfxboard; /* global Key so video(x) is unambiguous */
static int
htp_gfx_init(int force)
{
extern struct standcfg standcfg[];
struct htp_fncs *ptrbuf;
struct standcfg *s;
static int found;
void *base;
int x, y;
#ifdef MULTIHEAD
struct standcfg *first = 0;
int gX, board;
void *fbase;
char *p;
#endif
if (found && !force) /* We've already got one. */
return 0;
gfxboard = 0;
#ifdef MULTIHEAD
gX = board = 0;
if ((p=getenv("console")) && p && (*p == 'g') && isdigit(p[1]))
gX = p[1] - '0';
/* Find the gXth graphics board. If console is invalid, then
* fall back to the first found board.
*/
for (s = standcfg; s->install; s++) {
if (!s->gfxprobe)
continue;
while (base = (*s->gfxprobe)(0)) {
found = 1;
if (board++ == gX) {
init_board:
htp->hw = (void*)base;
(*s->gfxprobe)(&htp->fncs);
(*htp->fncs->init)((void*)base, &x, &y);
#if 1 /* XXX-TJN IDE was blanked */
(*htp->fncs->blankscreen)((void*)base, 1);
#endif
htp->xscreensize = x;
htp->yscreensize = y;
txMap(htp);
return(0);
}
if (!first) {
fbase = base;
first = s;
}
}
/* reset gfx drivers bard counter */
(*s->gfxprobe)(&ptrbuf);
}
if (first) {
s = first;
base = fbase;
goto init_board;
}
#else
#ifdef SN0
/* Find the only graphics board and init textport on it.
* Note that on SN0 systems, only one of the gfx standcfg
* entries will have a valid gfxprobe function.
*/
#else
/* Find the first graphics board and init textport on it.
*/
#endif
for (s = standcfg; s->install; s++) {
if (!s->gfxprobe)
continue;
base = (void *)(*s->gfxprobe)(0);
if (base) {
found = 1;
htp->hw = base;
(*s->gfxprobe)(&htp->fncs);
(*htp->fncs->init)(base, &x, &y);
(*htp->fncs->blankscreen)(base, 1);
htp->xscreensize = x;
htp->yscreensize = y;
txMap(htp);
return 0;
}
/* reset gfx drivers bard counter */
(*s->gfxprobe)(&ptrbuf);
}
#endif
return -1; /* cannot find any gfx board! */
}
static void _ttyputc(int c)
{
if (c == '\n')
cpu_errputc('\r');
cpu_errputc(c);
}
int
_init_htp(void)
{
extern int gfx_ok;
#if defined(IP22) || defined(IP28) || defined(IP30)
if (_mgras_run_ide) {
gfx_ok = htp_gfx_init(1);
return(gfx_ok);
}
#endif
_init_ttyputc(_ttyputc);
if (!gfx_ok) {
if (gfx_ok = (htp_gfx_init(0) != -1))
htp_init();
}
/* XXX--used to rely on calling twice to populate htp vectors in gfxgui
*/
if (gfx_ok)
initGfxGui(htp);
return(gfx_ok);
}
int
txPrint(char *c, int nc)
{
if (htp_write(c, nc) == 0)
return 0;
return 1;
}
/*
* Reset to a known state on soft reset
*/
static int
_gfxinit(void)
{
return(gfxISopen = 0);
}
static int
_gfxopen(IOBLOCK *io)
{
#ifndef _TP_COLOR
/* Currently do not support extended console since color makes
* scrolling slow plus is kinda sorta large.
*/
if (io->Flags & F_ECONS)
return(io->ErrorNumber = EINVAL);
#endif
_init_htp();
return _gfxReopen(io, 0);
}
static int
_gfxReopen(IOBLOCK *io, int dosetup)
{
#ifdef SN0
if ((!SN00)) { /* on SN00 Unit might be pci slot number */
/* validate unit (only allow 0) */
if (io->Unit)
return io->ErrorNumber = ENXIO;
}
#else
/* validate unit (only allow 0) */
if (io->Unit)
return io->ErrorNumber = ENXIO;
#endif
/* make multiple opens do nothing */
if (!dosetup && gfxISopen) {
gfxISopen++;
return ESUCCESS;
}
gfxalive = 0;
if (htp_gfx_init(dosetup) == -1) {
gfxISopen--;
syssetenv(GFX_ENV_VAR, GFX_DEAD);
return io->ErrorNumber = EIO;
}
/*
* Everything is working.
*/
if (getenv(GFX_ENV_VAR) == NULL)
syssetenv(GFX_ENV_VAR, GFX_OK);
gfxalive = 1;
syssetenv(GFX_ENV_VAR, GFX_OK);
gfxISopen++;
return ESUCCESS;
}
/*ARGSUSED*/
static int
_gfxclose(IOBLOCK *io)
{
if (gfxISopen == 1)
gfxISopen = 0;
return ESUCCESS;
}
static int
_gfxwrite(IOBLOCK *io)
{
if (!gfxalive)
return io->ErrorNumber = ENXIO;
ioctl(StandardIn,TIOCCHECKSTOP,0);
txPrint(io->Address, (int)io->Count);
return ESUCCESS;
}
static int
_gfxioctl(IOBLOCK *io)
{
if (!gfxalive)
return io->ErrorNumber = ENXIO;
switch ((__psint_t)io->IoctlCmd) {
case TIOCREOPEN:
/*
** It has been decided that a re-open for the graphics
** should reinitialize the graphics hardware.
*/
if (!io->IoctlArg)
return _gfxReopen(io, 1);
return(ESUCCESS);
case GIOCSETJMPBUF:
txSetJumpbuf((jmp_buf *)io->IoctlArg);
break;
case GIOCSETBUTSTR:
txSetString((char *)io->IoctlArg);
break;
default:
return io->ErrorNumber = EINVAL;
}
return 0;
}
/* ARCS - new stuff */
/*ARGSUSED*/
int
_gfx_strat(COMPONENT *self, IOBLOCK *iob)
{
switch (iob->FunctionCode) {
case FC_INITIALIZE:
return(_gfxinit());
case FC_OPEN:
return (_gfxopen (iob));
case FC_WRITE:
return (_gfxwrite (iob));
case FC_CLOSE:
return (_gfxclose (iob));
case FC_IOCTL:
return (_gfxioctl(iob));
case FC_READ:
default:
return(iob->ErrorNumber = EINVAL);
};
}
/* monitor template used by XXXXX/yy_init.c */
COMPONENT montmpl = {
PeripheralClass, /* Class */
MonitorPeripheral, /* Type */
(IDENTIFIERFLAG)0, /* Flags */
SGI_ARCS_VERS, /* Version */
SGI_ARCS_REV, /* Revision */
0, /* Key */
0x01, /* Affinity */
0, /* ConfigurationDataSize */
0, /* IdentifierLength */
0 /* Identifier */
};