Home | History | Annotate | Line # | Download | only in dev
ite_rt.c revision 1.4
      1 #include "ite.h"
      2 #if NITE > 0
      3 
      4 #include "param.h"
      5 #include "conf.h"
      6 #include "proc.h"
      7 #include "ioctl.h"
      8 #include "tty.h"
      9 #include "systm.h"
     10 
     11 #include "itevar.h"
     12 
     13 #include "machine/cpu.h"
     14 
     15 /* XXX */
     16 #include "grfioctl.h"
     17 #include "grfvar.h"
     18 #include "grf_rtreg.h"
     19 
     20 void retina_init(struct ite_softc *ip)
     21 {
     22   struct MonDef *md;
     23 
     24   if (ip->grf == 0)
     25     ip->grf = &grf_softc[ip - ite_softc];
     26 
     27   ip->priv = ip->grf->g_data;
     28   md = (struct MonDef *) ip->priv;
     29 
     30   ip->cols = md->TX;
     31   ip->rows = md->TY;
     32 }
     33 
     34 
     35 void retina_cursor(struct ite_softc *ip, int flag)
     36 {
     37       volatile u_char *ba = ip->grf->g_regkva;
     38 
     39       if (flag == ERASE_CURSOR)
     40         {
     41 	  /* disable cursor */
     42           WCrt (ba, CRT_ID_CURSOR_START, RCrt (ba, CRT_ID_CURSOR_START) | 0x20);
     43         }
     44       else
     45 	{
     46 	  int pos = ip->curx + ip->cury * ip->cols;
     47 
     48 	  /* make sure to enable cursor */
     49           WCrt (ba, CRT_ID_CURSOR_START, RCrt (ba, CRT_ID_CURSOR_START) & ~0x20);
     50 
     51 	  /* and position it */
     52 	  WCrt (ba, CRT_ID_CURSOR_LOC_HIGH, (u_char) (pos >> 8));
     53 	  WCrt (ba, CRT_ID_CURSOR_LOC_LOW,  (u_char) pos);
     54 
     55 	  ip->cursorx = ip->curx;
     56 	  ip->cursory = ip->cury;
     57 	}
     58 }
     59 
     60 
     61 
     62 static void screen_up (struct ite_softc *ip, int top, int bottom, int lines)
     63 {
     64 	volatile u_char * ba = ip->grf->g_regkva;
     65 	volatile u_char * fb = ip->grf->g_fbkva;
     66 	const struct MonDef * md = (struct MonDef *) ip->priv;
     67 #ifdef BANKEDDEVPAGER
     68 	int bank;
     69 #endif
     70 
     71 	/* do some bounds-checking here.. */
     72 	if (top >= bottom)
     73 	  return;
     74 
     75 	if (top + lines >= bottom)
     76 	  {
     77 	    retina_clear (ip, top, 0, bottom - top, ip->cols);
     78 	    return;
     79 	  }
     80 
     81 
     82 #ifdef BANKEDDEVPAGER
     83 	/* make sure to save/restore active bank (and if it's only
     84 	   for tests of the feature in text-mode..) */
     85 	bank = (RSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO)
     86 		| (RSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI) << 8));
     87 #endif
     88 
     89 	/* the trick here is to use a feature of the NCR chip. It can
     90 	   optimize data access in various read/write modes. One of
     91 	   the modes is able to read/write from/to different zones.
     92 
     93 	   Thus, by setting the read-offset to lineN, and the write-offset
     94 	   to line0, we just cause read/write cycles for all characters
     95 	   up to the last line, and have the chip transfer the data. The
     96 	   `addqb' are the cheapest way to cause read/write cycles (DONT
     97 	   use `tas' on the Amiga!), their results are completely ignored
     98 	   by the NCR chip, it just replicates what it just read. */
     99 
    100 		/* write to primary, read from secondary */
    101 	WSeq (ba, SEQ_ID_EXTENDED_MEM_ENA, (RSeq(ba, SEQ_ID_EXTENDED_MEM_ENA) & 0x1f) | 0 );
    102 		/* clear extended chain4 mode */
    103 	WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR, RSeq(ba, SEQ_ID_EXT_VIDEO_ADDR) & ~0x02);
    104 
    105 		/* set write mode 1, "[...] data in the read latches is written
    106 		   to memory during CPU memory write cycles. [...]" */
    107 	WGfx (ba, GCT_ID_GRAPHICS_MODE, (RGfx(ba, GCT_ID_GRAPHICS_MODE) & 0xfc) | 1);
    108 
    109 	{
    110 		/* write to line TOP */
    111 		long toploc = top * (md->TX / 16);
    112 		WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, ((unsigned char)toploc));
    113 		WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, ((unsigned char)(toploc >> 8)));
    114 	}
    115 	{
    116 		/* read from line TOP + LINES */
    117 		long fromloc = (top+lines) * (md->TX / 16);
    118 		WSeq (ba, SEQ_ID_SEC_HOST_OFF_LO, ((unsigned char)fromloc)) ;
    119 		WSeq (ba, SEQ_ID_SEC_HOST_OFF_HI, ((unsigned char)(fromloc >> 8))) ;
    120 	}
    121 	{
    122 		unsigned char * p = (unsigned char *) fb;
    123 		/* transfer all characters but LINES lines, unroll by 16 */
    124 		short x = (1 + bottom - (top + lines)) * (md->TX / 16) - 1;
    125 		do {
    126 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    127 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    128 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    129 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    130 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    131 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    132 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    133 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    134 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    135 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    136 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    137 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    138 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    139 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    140 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    141 			asm volatile("addqb #1,%0@+" : "=a" (p) : "0" (p));
    142 		} while (x--);
    143 	}
    144 
    145 		/* reset to default values */
    146 	WSeq (ba, SEQ_ID_SEC_HOST_OFF_HI, 0);
    147 	WSeq (ba, SEQ_ID_SEC_HOST_OFF_LO, 0);
    148 	WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, 0);
    149 	WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, 0);
    150 		/* write mode 0 */
    151 	WGfx (ba, GCT_ID_GRAPHICS_MODE, (RGfx(ba, GCT_ID_GRAPHICS_MODE) & 0xfc) | 0);
    152 		/* extended chain4 enable */
    153 	WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR , RSeq(ba, SEQ_ID_EXT_VIDEO_ADDR) | 0x02);
    154 		/* read/write to primary on A0, secondary on B0 */
    155 	WSeq (ba, SEQ_ID_EXTENDED_MEM_ENA, (RSeq(ba, SEQ_ID_EXTENDED_MEM_ENA) & 0x1f) | 0x40 );
    156 
    157 
    158 	/* fill the free lines with spaces */
    159 
    160 	{  /* feed latches with value */
    161 		unsigned short * f = (unsigned short *) fb;
    162 
    163 		f += (1 + bottom - lines) * md->TX * 2;
    164 		*f = 0x2010;
    165 		{
    166 			volatile unsigned short dummy = *((volatile unsigned short *)f);
    167 		}
    168 	}
    169 
    170 	   /* clear extended chain4 mode */
    171 	WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR, RSeq(ba, SEQ_ID_EXT_VIDEO_ADDR) & ~0x02);
    172 	   /* set write mode 1, "[...] data in the read latches is written
    173 	      to memory during CPU memory write cycles. [...]" */
    174 	WGfx (ba, GCT_ID_GRAPHICS_MODE, (RGfx(ba, GCT_ID_GRAPHICS_MODE) & 0xfc) | 1);
    175 
    176 	{
    177 		unsigned long * p = (unsigned long *) fb;
    178 		short x = (lines * (md->TX/16)) - 1;
    179 		const unsigned long dummyval = 0;
    180 
    181 		p += (1 + bottom - lines) * (md->TX/4);
    182 
    183 		do {
    184 			*p++ = dummyval;
    185 			*p++ = dummyval;
    186 			*p++ = dummyval;
    187 			*p++ = dummyval;
    188 		} while (x--);
    189 	}
    190 
    191 	   /* write mode 0 */
    192 	WGfx (ba, GCT_ID_GRAPHICS_MODE, (RGfx(ba, GCT_ID_GRAPHICS_MODE) & 0xfc) | 0);
    193 	   /* extended chain4 enable */
    194 	WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR , RSeq(ba, SEQ_ID_EXT_VIDEO_ADDR) | 0x02);
    195 
    196 #ifdef BANKEDDEVPAGER
    197 	/* restore former bank */
    198 	WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, (unsigned char) bank);
    199 	bank >>= 8;
    200 	WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, (unsigned char) bank);
    201 #endif
    202 };
    203 
    204 static void screen_down (struct ite_softc *ip, int top, int bottom, int lines)
    205 {
    206 	volatile u_char * ba = ip->grf->g_regkva;
    207 	volatile u_char * fb = ip->grf->g_fbkva;
    208 	const struct MonDef * md = (struct MonDef *) ip->priv;
    209 #ifdef BANKEDDEVPAGER
    210 	int bank;
    211 #endif
    212 
    213 	/* do some bounds-checking here.. */
    214 	if (top >= bottom)
    215 	  return;
    216 
    217 	if (top + lines >= bottom)
    218 	  {
    219 	    retina_clear (ip, top, 0, bottom - top, ip->cols);
    220 	    return;
    221 	  }
    222 
    223 #ifdef BANKEDDEVPAGER
    224 	/* make sure to save/restore active bank (and if it's only
    225 	   for tests of the feature in text-mode..) */
    226 	bank = (RSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO)
    227 		| (RSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI) << 8));
    228 #endif
    229 	/* see screen_up() for explanation of chip-tricks */
    230 
    231 		/* write to primary, read from secondary */
    232 	WSeq (ba, SEQ_ID_EXTENDED_MEM_ENA, (RSeq(ba, SEQ_ID_EXTENDED_MEM_ENA) & 0x1f) | 0 );
    233 		/* clear extended chain4 mode */
    234 	WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR, RSeq(ba, SEQ_ID_EXT_VIDEO_ADDR) & ~0x02);
    235 
    236 		/* set write mode 1, "[...] data in the read latches is written
    237 		   to memory during CPU memory write cycles. [...]" */
    238 	WGfx (ba, GCT_ID_GRAPHICS_MODE, (RGfx(ba, GCT_ID_GRAPHICS_MODE) & 0xfc) | 1);
    239 
    240 	{
    241 		/* write to line TOP + LINES */
    242 		long toloc = (top + lines) * (md->TX / 16);
    243 		WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, ((unsigned char)toloc));
    244 		WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, ((unsigned char)(toloc >> 8)));
    245 	}
    246 	{
    247 		/* read from line TOP */
    248 		long fromloc = top * (md->TX / 16);
    249 		WSeq (ba, SEQ_ID_SEC_HOST_OFF_LO, ((unsigned char)fromloc));
    250 		WSeq (ba, SEQ_ID_SEC_HOST_OFF_HI, ((unsigned char)(fromloc >> 8))) ;
    251 	}
    252 
    253 	{
    254 		unsigned char * p = (unsigned char *) fb;
    255 		short x = (1 + bottom - (top + lines)) * (md->TX / 16) - 1;
    256 		p += (1 + bottom - (top + lines)) * md->TX;
    257 		do {
    258 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    259 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    260 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    261 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    262 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    263 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    264 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    265 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    266 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    267 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    268 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    269 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    270 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    271 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    272 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    273 			asm volatile("addqb #1,%0@-" : "=a" (p) : "0" (p));
    274 		} while (x--);
    275 	}
    276 
    277 	WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, 0);
    278 	WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, 0);
    279 	WSeq (ba, SEQ_ID_SEC_HOST_OFF_HI, 0);
    280 	WSeq (ba, SEQ_ID_SEC_HOST_OFF_LO, 0);
    281 
    282 		/* write mode 0 */
    283 	WGfx (ba, GCT_ID_GRAPHICS_MODE, (RGfx(ba, GCT_ID_GRAPHICS_MODE) & 0xfc) | 0);
    284 		/* extended chain4 enable */
    285 	WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR , RSeq(ba, SEQ_ID_EXT_VIDEO_ADDR) | 0x02);
    286 		/* read/write to primary on A0, secondary on B0 */
    287 	WSeq (ba, SEQ_ID_EXTENDED_MEM_ENA, (RSeq(ba, SEQ_ID_EXTENDED_MEM_ENA) & 0x1f) | 0x40 );
    288 
    289 	/* fill the free lines with spaces */
    290 
    291 	{  /* feed latches with value */
    292 		unsigned short * f = (unsigned short *) fb;
    293 
    294 		f += top * md->TX * 2;
    295 		*f = 0x2010;
    296 		{
    297 			volatile unsigned short dummy = *((volatile unsigned short *)f);
    298 		}
    299 	}
    300 
    301 	   /* clear extended chain4 mode */
    302 	WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR, RSeq(ba, SEQ_ID_EXT_VIDEO_ADDR) & ~0x02);
    303 	   /* set write mode 1, "[...] data in the read latches is written
    304 	      to memory during CPU memory write cycles. [...]" */
    305 	WGfx (ba, GCT_ID_GRAPHICS_MODE, (RGfx(ba, GCT_ID_GRAPHICS_MODE) & 0xfc) | 1);
    306 
    307 	{
    308 		unsigned long * p = (unsigned long *) fb;
    309 		short x = (lines * (md->TX/16)) - 1;
    310 		const unsigned long dummyval = 0;
    311 
    312 		p += top * (md->TX/4);
    313 
    314 		do {
    315 			*p++ = dummyval;
    316 			*p++ = dummyval;
    317 			*p++ = dummyval;
    318 			*p++ = dummyval;
    319 		} while (x--);
    320 	}
    321 
    322 	   /* write mode 0 */
    323 	WGfx (ba, GCT_ID_GRAPHICS_MODE, (RGfx(ba, GCT_ID_GRAPHICS_MODE) & 0xfc) | 0);
    324 	   /* extended chain4 enable */
    325 	WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR , RSeq(ba, SEQ_ID_EXT_VIDEO_ADDR) | 0x02);
    326 
    327 #ifdef BANKEDDEVPAGER
    328 	/* restore former bank */
    329 	WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, (unsigned char) bank);
    330 	bank >>= 8;
    331 	WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, (unsigned char) bank);
    332 #endif
    333 };
    334 
    335 void retina_deinit(struct ite_softc *ip)
    336 {
    337   ip->flags &= ~ITE_INITED;
    338 }
    339 
    340 
    341 void retina_putc(struct ite_softc *ip, int c, int dy, int dx, int mode)
    342 {
    343 	volatile u_char * ba = ip->grf->g_regkva;
    344 	volatile u_char * fb = ip->grf->g_fbkva;
    345 	register u_char attr;
    346 
    347 	attr = (mode & ATTR_INV) ? 0x21 : 0x10;
    348 	if (mode & ATTR_UL)     attr  = 0x01;	/* ???????? */
    349 	if (mode & ATTR_BOLD)   attr |= 0x08;
    350 	if (mode & ATTR_BLINK)	attr |= 0x80;
    351 
    352 	fb += 4 * (dy * ip->cols + dx);
    353 	*fb++ = c; *fb = attr;
    354 }
    355 
    356 void retina_clear(struct ite_softc *ip, int sy, int sx, int h, int w)
    357 {
    358 	volatile u_char * ba = ip->grf->g_regkva;
    359 	u_short * fb = (u_short *) ip->grf->g_fbkva;
    360 	short x;
    361 	const u_short fillval = 0x2010;
    362 	/* could probably be optimized just like the scrolling functions !! */
    363 	fb += 2 * (sy * ip->cols + sx);
    364 	while (h--)
    365 	  {
    366 	    for (x = 2 * (w - 1); x >= 0; x -= 2)
    367 	      fb[x] = fillval;
    368 	    fb += 2 * ip->cols;
    369 	  }
    370 }
    371 
    372 void retina_scroll(struct ite_softc *ip, int sy, int sx, int count, int dir)
    373 {
    374   volatile u_char * ba = ip->grf->g_regkva;
    375   u_long * fb = (u_long *) ip->grf->g_fbkva;
    376   register int height, dy, i;
    377 
    378   retina_cursor(ip, ERASE_CURSOR);
    379 
    380   if (dir == SCROLL_UP)
    381     {
    382       screen_up (ip, sy - count, ip->bottom_margin, count);
    383       /* bcopy (fb + sy * ip->cols, fb + (sy - count) * ip->cols, 4 * (ip->bottom_margin - sy + 1) * ip->cols); */
    384       /* retina_clear (ip, ip->bottom_margin + 1 - count, 0, count, ip->cols); */
    385     }
    386   else if (dir == SCROLL_DOWN)
    387     {
    388       screen_down (ip, sy, ip->bottom_margin, count);
    389       /* bcopy (fb + sy * ip->cols, fb + (sy + count) * ip->cols, 4 * (ip->bottom_margin - sy - count + 1) * ip->cols); */
    390       /* retina_clear (ip, sy, 0, count, ip->cols); */
    391     }
    392   else if (dir == SCROLL_RIGHT)
    393     {
    394       bcopy (fb + sx + sy * ip->cols, fb + sx + sy * ip->cols + count, 4 * (ip->cols - (sx + count)));
    395       retina_clear (ip, sy, sx, 1, count);
    396     }
    397   else
    398     {
    399       bcopy (fb + sx + sy * ip->cols, fb + sx - count + sy * ip->cols, 4 * (ip->cols - sx));
    400       retina_clear (ip, sy, ip->cols - count, 1, count);
    401     }
    402 }
    403 
    404 #endif
    405 
    406 
    407 
    408