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

493 lines
13 KiB
C

/*
* gr2_tport.c
*
* GR2 textport functions.
*
*
* Copyright 1991, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
#ident "$Revision: 1.22 $"
#include <sys/gr2hw.h>
#include <sys/cpu.h>
#include <sys/gr2_if.h>
#include <sys/param.h>
#include <sys/sema.h>
#include <sys/gr2.h>
#include <sys/sbd.h>
#include <sys/gr2.h>
#include "stand_htport.h"
#include "cursor.h"
#include <libsc.h>
#if defined(IP19) || defined(IP21) || defined(IP25)
#include <libsk.h>
#include <sys/EVEREST/everest.h>
#include <sys/EVEREST/evconfig.h>
#include <sys/EVEREST/io4.h>
#include <sys/EVEREST/dang.h>
extern int tport_window, tport_adap;
#endif
/*****************************************************************************
*
* All writes to the pipe are protected from interrupts so that interrupt
* routines can do printf's on the textport. Otherwise we would hose the
* pipe when we did a printf from an interrupt routine.
*
* This may not be necessary since this is probably done at a higher level.
*
*****************************************************************************/
/*
* Wait until FIFO no longer full.
*
* Wait until vertical retrace.
*
* These look at the CPU interrupt not the interrupt status reg. on a
* particular graphics board (i.e. not checking for multiple heads).
*/
#if defined(IP19) || defined(IP21) || defined(IP25)
extern volatile long long *dang_ptr;
#define GEWAIT()\
{ int reg; int i = 0; \
while (((load_double((long long *)(&dang_ptr[DANG_WG_WDCNT]))) > 50) && (i++ < 1000000)); \
if (i >= 999999) { \
reg = load_double((long long *)(&dang_ptr[DANG_WG_WDCNT])); \
ttyprintf("GEWAIT timedout, stop, fifocnt = %d\n",reg);\
while (i);/*sit-n-spin*/\
}\
}
#else
#define GEWAIT() \
while (*((volatile unsigned char*)PHYS_TO_K1(LIO_0_ISR_ADDR)) & LIO_FIFO)
#endif
#if defined(IP19)
static volatile struct _expPipeEntryRec *wg = (volatile struct _expPipeEntryRec *)EV_WGINPUT_BASE;
#define FIFO(x,y) wg[(x)].pipeUnion.l = (y)
#define FLUSHWG wg[0xff].pipeUnion.l = 0
#elif defined(IP21)
#define EVEN_OFFSET 0
#define FLUSH_OFFSET 4
static volatile union _expPipeEntryRec *wg = (volatile union _expPipeEntryRec *)EV_WGINPUT_BASE;
#define FIFO(x,y) { wg[EVEN_OFFSET].i = (x); wg[EVEN_OFFSET].i = (y); }
#define FLUSHWG wg[FLUSH_OFFSET].i = 0
#elif defined(IP25)
static volatile union _expPipeEntryRec *wg = (volatile union _expPipeEntryRec *)EV_WGINPUT_BASE;
#define FIFO(x,y) { wg[0].i = (x); wg[0].i = (y); }
#define FLUSHWG load_double((long long *)&dang_ptr[DANG_UPPER_GIO_ADDR])
#else
#define FIFO(x,y) base->fifo[(x)] = (y)
#define FLUSHWG
#endif
#if defined (FLAT_PANEL)
#include "sys/fpanel.h"
static char flat_panel; /* 0 - no flat panel */
/* MONITORID_CORONA = 1024x768 flat panel */
/* MONITORID_ICHIBAN = 1280x1024 flat panel */
#endif /* FLAT_PANEL */
/******************************************************************************
* Turn Screen On/Off
*****************************************************************************/
static void Gr2TpBlankscreen(void *hw, int blank)
{
register struct gr2_hw *base = (struct gr2_hw *)hw;
if (blank) {
/* Turn off DAC display*/
base->reddac.addr = GR2_DAC_READMASK;
base->reddac.cmd2 = 0;
base->grndac.addr = GR2_DAC_READMASK;
base->grndac.cmd2 = 0;
base->bluedac.addr = GR2_DAC_READMASK;
base->bluedac.cmd2 = 0;
} else {
/* Turn on DAC display*/
base->reddac.addr = GR2_DAC_READMASK;
base->reddac.cmd2 = 0xff;
base->grndac.addr = GR2_DAC_READMASK;
base->grndac.cmd2 = 0xff;
base->bluedac.addr = GR2_DAC_READMASK;
base->bluedac.cmd2 = 0xff;
#if defined(FLAT_PANEL)
if (flat_panel)
i2cPanelOn(); /* ensure panel is on. */
#endif /* FLAT_PANEL */
}
}
/*****************************************************************************
* Set the current color.
*****************************************************************************/
static void Gr2TpColor(void *hw, int color)
{
register struct gr2_hw *base = (struct gr2_hw *)hw;
GEWAIT();
FIFO(PUC_COLOR,color);
#ifdef EVEREST
FLUSHWG;
#endif
}
/*****************************************************************************
* Create colormap entries in the XMAP chip.
*****************************************************************************/
void Gr2TpMapcolor(void *hw, int index, int red, int green, int blue)
{
register struct gr2_hw *base = (struct gr2_hw *)hw;
/* Index to 8-bit color map */
index += 4096;
GEWAIT();
base->xmapall.addrhi = (index & 0x1f00) >> 8;
base->xmapall.addrlo = index & 0xff;
base->xmapall.clut = red;
base->xmapall.clut = green;
base->xmapall.clut = blue;
}
/*****************************************************************************
* Draw a filled, screen aligned rectangle.
*****************************************************************************/
static void Gr2TpSboxfi(void *hw, int x1, int y1, int x2, int y2)
{
register struct gr2_hw *base = (struct gr2_hw *)hw;
#if defined (FLAT_PANEL)
if (flat_panel == MONITORID_CORONA) {
y1 += 256; /* adjust for low-res display */
y2 += 256;
}
#endif /* FLAT_PANEL */
GEWAIT();
FIFO(PUC_RECTI2D,x1);
FIFO(PUC_DATA,y1);
FIFO(PUC_DATA,x2);
FIFO(PUC_DATA,y2);
#ifdef EVEREST
FLUSHWG;
#endif
}
/*****************************************************************************
* Draw a pixel at the given screen coordinate.
*****************************************************************************/
static void Gr2TpPnt2i(void *hw, int x, int y)
{
register struct gr2_hw *base = (struct gr2_hw *)hw;
#if defined (FLAT_PANEL)
if (flat_panel == MONITORID_CORONA)
y += 256; /* adjust for low-res display */
#endif /* FLAT_PANEL */
GEWAIT();
FIFO(PUC_PNT2I,x);
FIFO(PUC_DATA,y);
#ifdef EVEREST
FLUSHWG;
#endif
}
/*****************************************************************************
* Specify the position at which characters should be drawn.
*****************************************************************************/
static void Gr2TpCmov2i(void *hw, int x, int y)
{
register struct gr2_hw *base = (struct gr2_hw *)hw;
#if defined (FLAT_PANEL)
if (flat_panel == MONITORID_CORONA)
y += 256; /* adjust for low-res display */
#endif /* FLAT_PANEL */
GEWAIT();
FIFO(PUC_CMOV2I,x);
FIFO(PUC_DATA,y);
#ifdef EVEREST
FLUSHWG;
#endif
}
/*****************************************************************************
* Output a character bitmap.
*****************************************************************************/
static void Gr2TpDrawBitmap(void *hw, struct htp_bitmap *b)
{
#define GR2MAXW 32
register struct gr2_hw *base = (struct gr2_hw *)hw;
register unsigned short *buf;
register int tmp1;
int xsize, ysize, yorig;
int sper = b->sper;
int xoffset = 0;
int bufset = 0;
int xleft = b->xsize;
nextcolumn:
buf = b->buf + bufset;
ysize = b->ysize;
xsize = (xleft > 32) ? 32 : xleft;
yorig = b->yorig;
while (ysize > 18) {
GEWAIT();
FIFO(PUC_DRAWCHAR,xsize);
FIFO(PUC_DATA,18); /* 18 is max height in ucode */
FIFO(PUC_DATA,(sper > 1) ? 2 : 1);
FIFO(PUC_DATA,b->xorig - xoffset);
FIFO(PUC_DATA,yorig);
FIFO(PUC_DATA,0); /* xmove and ymove are zero */
FIFO(PUC_DATA,0);
if (sper > 1) {
for (tmp1 = 0; tmp1 < 18; tmp1++) {
FIFO(PUC_DATA,((*buf)<<16)|(*(buf+1)));
buf += b->sper;
}
} else if (sper == 1) {
for (tmp1 = 0; tmp1 < 18; tmp1++) {
FIFO(PUC_DATA,*buf);
buf += b->sper;
}
}
ysize -= 18;
yorig -= 18;
}
FLUSHWG;
GEWAIT();
FIFO(PUC_DRAWCHAR,xsize);
FIFO(PUC_DATA,ysize);
FIFO(PUC_DATA,(sper > 1) ? 2 : 1);
FIFO(PUC_DATA,b->xorig - xoffset);
FIFO(PUC_DATA,yorig);
FIFO(PUC_DATA,b->xmove);
FIFO(PUC_DATA,0); /* ymove is zero */
tmp1 = 0;
if (sper > 1) {
for ( ; tmp1 < 18; tmp1++) {
FIFO(PUC_DATA,((*buf)<<16)|(*(buf+1)));
buf += b->sper;
}
} else {
for ( ; tmp1 < ysize; tmp1++) {
FIFO(PUC_DATA,*buf);
buf += b->sper;
}
}
while (tmp1++ < 18) {
FIFO(PUC_DATA,0);
}
if (sper > 2) {
sper -= 2;
xoffset += 32;
xleft -= 32;
bufset += 2;
goto nextcolumn;
}
#if defined(IP19) || defined(IP21) || defined(IP25)
FLUSHWG;
#endif
}
/*****************************************************************************
* Initialize the GR2 textport.
*****************************************************************************/
static void Gr2TpInit(void *hw, int *x, int *y)
{
extern struct gr2_info *getGr2Info(void *hw);
struct gr2_info *gr2 = getGr2Info(hw);
if (gr2) {
*x = gr2->gfx_info.xpmax;
*y = gr2->gfx_info.ypmax;
#if defined (FLAT_PANEL)
if (gr2->MonitorType == MONITORID_CORONA ||
gr2->MonitorType == MONITORID_ICHIBAN)
flat_panel = gr2->MonitorType;
else
flat_panel = 0;
if (flat_panel) {
Gr2TpMapcolor(hw,0,0,0,0);
Gr2TpColor(hw,0);
i2cPanelOn();
Gr2TpSboxfi(hw,0,0,(*x)-1,(*y)-1);
}
#endif /* FLAT_PANEL */
}
#if defined (FLAT_PANEL)
else
flat_panel = 0;
#endif /* FLAT_PANEL */
}
/*****************************************************************************
* Move cursor.
*****************************************************************************/
static void Gr2TpMovec(void *hw, int x, int y)
{
register struct gr2_hw *base = (struct gr2_hw *)hw;
extern struct htp_state *htp;
int screenx, screeny;
/*
* Find x origin of cursor bitmap
*/
screenx = x - tp_ptr_x_hot;
/*
* If the cursor x position crosses the border from right to left,
* or left to right, respectively, then change timing table.
* Only needed on high-res displays. We can assume in any
* case that the vc1 VID_EP pointer is initialized elsewhere.
*/
#if defined (FLAT_PANEL)
if (flat_panel != MONITORID_CORONA) {
#endif /* FLAT_PANEL */
if (screenx < 32) {
/* Cross from right to left*/
/* Add horzontal offset */
screenx += GR2_CURS_XOFF_1280;
base->vc1.addrhi = (GR2_VID_EP >> 8) & 0xff;
base->vc1.addrlo = GR2_VID_EP & 0xff;
base->vc1.cmd0 = GR2_VIDTIM_FRMT_BASE;
} else {
/* Cross from left to right*/
base->vc1.addrhi = (GR2_VID_EP >> 8) & 0xff;
base->vc1.addrlo = GR2_VID_EP & 0xff;
base->vc1.cmd0 = GR2_VIDTIM_CURSFRMT_BASE;
}
#if defined (FLAT_PANEL)
}
#endif /* FLAT_PANEL */
/* Y origin of bitmap */
screeny = y - tp_ptr_y_hot;
#if defined (FLAT_PANEL)
if (flat_panel == MONITORID_CORONA) {
screenx += GR2_CURS_XOFF_CORONA;
screeny += GR2_CURS_YOFF_CORONA;
}
else
#endif /* FLAT_PANEL */
screeny += GR2_CURS_YOFF_1280;
/* Write x, y values */
base->vc1.addrhi = (GR2_CUR_XL >> 8) & 0xff;
base->vc1.addrlo = GR2_CUR_XL & 0xff;
base->vc1.cmd0 = screenx;
base->vc1.cmd0 = screeny;
}
static void
Gr2TpBmove(void *hw, int oldx, int oldy, int newx, int newy, int w, int h)
{
register struct gr2_hw *base = (struct gr2_hw *)hw;
int word_len = ((w+3)>>2);
int max_lines_stored = 4864 / word_len; /* reserved shram area size */
#if defined (FLAT_PANEL)
int screenheight;
if (flat_panel == MONITORID_CORONA)
screenheight = 768;
else
screenheight = 1024;
#else /* FLAT_PANEL */
#define screenheight 1024
#endif /* FLAT_PANEL */
/* gr2 rectcopy ucode uses Xish coordinates */
oldy = screenheight - oldy - h;
newy = screenheight - newy - h;
if ((newy <= oldy) || (h <= max_lines_stored)) {
GEWAIT();
FIFO(PUC_RECTCOPY,word_len);
FIFO(PUC_DATA,max_lines_stored);
FIFO(PUC_DATA,oldx);
FIFO(PUC_DATA,oldy);
FIFO(PUC_DATA,w);
FIFO(PUC_DATA,h);
FIFO(PUC_DATA,newx);
FIFO(PUC_DATA,newy);
}
else {
int srcy, dsty, draw_height;
srcy = oldy + h - max_lines_stored;
dsty = newy + h - max_lines_stored;
draw_height = _min(h,max_lines_stored);
while (draw_height) {
GEWAIT();
FIFO(PUC_RECTCOPY,word_len);
FIFO(PUC_DATA,max_lines_stored);
FIFO(PUC_DATA,oldx);
FIFO(PUC_DATA,srcy);
FIFO(PUC_DATA,w);
FIFO(PUC_DATA,draw_height);
FIFO(PUC_DATA,newx);
FIFO(PUC_DATA,dsty);
h -= draw_height;
draw_height = _min(h,max_lines_stored);
srcy -= draw_height;
dsty -= draw_height;
}
}
#ifdef EVEREST
FLUSHWG;
#endif
return;
}
/*****************************************************************************
* Host Textport routines. This is the interface with htport.
*****************************************************************************/
struct htp_fncs gr2_tp_fncs = {
Gr2TpBlankscreen,
Gr2TpColor,
Gr2TpMapcolor,
Gr2TpSboxfi,
Gr2TpPnt2i,
Gr2TpCmov2i,
Gr2TpDrawBitmap,
Gr2TpBmove,
Gr2TpInit,
Gr2TpMovec,
};