summaryrefslogtreecommitdiff
path: root/sys/arch/amiga/dev/grf_cv.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amiga/dev/grf_cv.c')
-rw-r--r--sys/arch/amiga/dev/grf_cv.c636
1 files changed, 428 insertions, 208 deletions
diff --git a/sys/arch/amiga/dev/grf_cv.c b/sys/arch/amiga/dev/grf_cv.c
index 1dc6fddfc17..034cd957ae7 100644
--- a/sys/arch/amiga/dev/grf_cv.c
+++ b/sys/arch/amiga/dev/grf_cv.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: grf_cv.c,v 1.14 1997/01/16 09:24:13 niklas Exp $ */
-/* $NetBSD: grf_cv.c,v 1.20 1996/12/23 09:10:05 veego Exp $ */
+/* $OpenBSD: grf_cv.c,v 1.15 1997/09/18 13:39:49 niklas Exp $ */
+/* $NetBSD: grf_cv.c,v 1.24 1997/07/30 11:05:55 veego Exp $ */
/*
* Copyright (c) 1995 Michael Teske
@@ -16,7 +16,7 @@
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ezra Story, by Kari
- * Mettinen and by Bernd Ernesti.
+ * Mettinen, Michael Teske and by Bernd Ernesti.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
@@ -39,18 +39,12 @@
*
* Modified for CV64 from
* Kari Mettinen's Cirrus driver by Michael Teske 10/95
- * For questions mail me at teske@mail.desy.de
*
* Thanks to Tekelec Airtronic for providing me with a S3 Trio64 documentation.
* Thanks to Bernd 'the fabulous bug-finder' Ernesti for bringing my messy
* source to NetBSD style :)
- *
- * TODO:
- * Bugfree Hardware Cursor support.
- * The HWC routines provided here are buggy in 16/24 bit
- * and may cause a Vertical Bar Crash of the Trio64.
- * On the other hand it's better to put the routines in the Xserver,
- * so please _don't_ put CV_HARDWARE_CURSOR in your config file.
+ * Thanks to Harald Koenig for providing information about undocumented
+ * Trio64 Bugs.
*/
#include <sys/param.h>
@@ -59,10 +53,16 @@
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/systm.h>
+#include <sys/syslog.h>
+
#include <machine/cpu.h>
+#include <machine/intr.h>
+
#include <dev/cons.h>
+
#include <amiga/dev/itevar.h>
#include <amiga/amiga/device.h>
+#include <amiga/amiga/isr.h>
#include <amiga/dev/grfioctl.h>
#include <amiga/dev/grfvar.h>
#include <amiga/dev/grf_cvreg.h>
@@ -72,8 +72,9 @@ int grfcvmatch __P((struct device *, void *, void *));
void grfcvattach __P((struct device *, struct device *, void *));
int grfcvprint __P((void *, const char *));
-static int cv_has_4mb __P((volatile caddr_t));
-static unsigned short cv_compute_clock __P((unsigned long));
+int cvintr __P((void *));
+int cv_has_4mb __P((volatile caddr_t));
+unsigned short cv_compute_clock __P((unsigned long));
void cv_boardinit __P((struct grf_softc *));
int cv_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
int cv_setvmode __P((struct grf_softc *, unsigned int));
@@ -87,20 +88,27 @@ int cv_toggle __P((struct grf_softc *));
int cv_mondefok __P((struct grfvideo_mode *));
int cv_load_mon __P((struct grf_softc *, struct grfcvtext_mode *));
void cv_inittextmode __P((struct grf_softc *));
-static inline void cv_write_port __P((unsigned short, volatile caddr_t));
-static inline void cvscreen __P((int, volatile caddr_t));
-static inline void gfx_on_off __P((int, volatile caddr_t));
+static __inline void cv_write_port __P((unsigned short, volatile caddr_t));
+static __inline void cvscreen __P((int, volatile caddr_t));
+static __inline void gfx_on_off __P((int, volatile caddr_t));
-#ifdef CV_HARDWARE_CURSOR
+#ifndef CV_NO_HARDWARE_CURSOR
int cv_getspritepos __P((struct grf_softc *, struct grf_position *));
int cv_setspritepos __P((struct grf_softc *, struct grf_position *));
+static __inline short M2I __P((short));
int cv_getspriteinfo __P((struct grf_softc *,struct grf_spriteinfo *));
-void cv_setup_hwc __P((struct grf_softc *,
- unsigned char, unsigned char, unsigned char, unsigned char,
- const unsigned long *));
+void cv_setup_hwc __P((struct grf_softc *));
int cv_setspriteinfo __P((struct grf_softc *,struct grf_spriteinfo *));
int cv_getspritemax __P((struct grf_softc *,struct grf_position *));
-#endif /* CV_HARDWARE_CURSOR */
+#endif /* !CV_NO_HARDWARE_CURSOR */
+
+/*
+ * Extension to grf_softc for interrupt support
+ */
+struct grf_cv_softc {
+ struct grf_softc gcs_sc;
+ struct isr gcs_isr;
+};
/* Graphics display definitions.
* These are filled by 'grfconfig' using GRFIOCSETMON.
@@ -137,8 +145,8 @@ extern unsigned char S3FONT[];
* (Internally, we still have to use hvalues/8!)
*/
struct grfcvtext_mode cvconsole_mode = {
- {255, "", 25000000, 640, 480, 4, 640/8, 784/8, 680/8, 768/8, 800/8,
- 481, 521, 491, 493, 525},
+ { 255, "", 25000000, 640, 480, 4, 640/8, 680/8, 768/8, 800/8,
+ 481, 521, 491, 493, 525 },
8, S3FONTY, 80, 480 / S3FONTY, S3FONT, 32, 255
};
@@ -250,7 +258,7 @@ long cv_memclk = 50000000;
/* standard driver stuff */
struct cfattach grfcv_ca = {
- sizeof(struct grf_softc), grfcvmatch, grfcvattach
+ sizeof(struct grf_cv_softc), grfcvmatch, grfcvattach
};
struct cfdriver grfcv_cd = {
@@ -258,6 +266,85 @@ struct cfdriver grfcv_cd = {
};
static struct cfdata *grfcv_cfdata;
+#define CV_INT_NUM 6 /* CV interrupt Level: #2 or #6 */
+#define CV_ULCURSOR 1 /* Underlined Cursor in textmode */
+
+#ifndef CV_NO_HARDWARE_CURSOR
+
+#define HWC_OFF (cv_fbsize - 1024*2)
+#define HWC_SIZE 1024
+
+static unsigned short cv_cursor_storage[HWC_SIZE/2];
+static short curs_update_flag = 0;
+#endif /* !CV_NO_HARDWARE_CURSOR */
+
+/*
+ * Interrupt handler
+ * This is used for updating the cursor shape (because it _must not_
+ * be changed while cursor is displayed)
+ * and maybe later to avoid busy waiting
+ * for Vertical Blank and/or gfx engine busy
+ */
+int
+cvintr(arg)
+ void * arg;
+{
+#ifndef CV_NO_HARDWARE_CURSOR
+ register unsigned long *csrc, *cdest;
+ int i;
+#endif /* !CV_NO_HARDWARE_CURSOR */
+ struct grf_softc *gp = arg;
+ volatile caddr_t ba = gp->g_regkva;
+ unsigned char test;
+ unsigned char cridx; /* Save the cr Register index */
+
+ if (gp == NULL)
+ return 0;
+
+ test = vgar(ba, GREG_INPUT_STATUS0_R);
+
+ if (test & 0x80) { /* VR int pending */
+ /* Save old CR index */
+ cridx = vgar (ba, CRT_ADDRESS);
+
+#if 0
+ test = RCrt(ba, CRT_ID_END_VER_RETR);
+ /* Clear int (bit 4) */
+ test &= ~0x10;
+ WCrt(ba, CRT_ID_END_VER_RETR, test);
+#else
+ vgaw(ba, CRT_ADDRESS, CRT_ID_END_VER_RETR);
+ asm volatile ("bclr #4,%0@(0x3d5);nop" : : "a" (ba));
+#endif
+
+#ifndef CV_NO_HARDWARE_CURSOR
+ /* update the hardware cursor, if necessary */
+ if (curs_update_flag) {
+ csrc = (unsigned long *)cv_cursor_storage;
+ cdest = (unsigned long *)((volatile char *)gp->g_fbkva
+ + HWC_OFF);
+ for (i = 0; i < HWC_SIZE / sizeof(long); i++)
+ *cdest++ = *csrc++;
+ curs_update_flag = 0;
+ }
+ /* Reenable int */
+#if 0
+ test |= 0x10;
+ WCrt(ba, CRT_ID_END_VER_RETR, test);
+#else
+ /* I don't trust the optimizer here... */
+ asm volatile ("bset #4,%0@(0x3d5);nop" : : "a" (ba));
+#endif
+ cv_setspritepos (gp, NULL);
+
+ /* Restore the old CR index */
+ vgaw(ba, CRT_ADDRESS, cridx);
+ __asm volatile ("nop");
+#endif /* !CV_NO_HARDWARE_CURSOR */
+ return (1);
+ }
+ return (0);
+}
/*
* Get frambuffer memory size.
@@ -265,7 +352,7 @@ static struct cfdata *grfcv_cfdata;
* so we have to do it this way.
* Return 0 for 2MB, 1 for 4MB
*/
-static int
+int
cv_has_4mb(fb)
volatile caddr_t fb;
{
@@ -301,7 +388,7 @@ grfcvmatch(pdp, match, auxp)
#ifdef CV64CONSOLE
struct cfdata *cfp = match;
static int cvcons_unit = -1;
-#endif
+#endif /* CV64CONSOLE */
struct zbus_args *zap;
zap = auxp;
@@ -309,7 +396,7 @@ grfcvmatch(pdp, match, auxp)
if (amiga_realconfig == 0)
#ifdef CV64CONSOLE
if (cvcons_unit != -1)
-#endif
+#endif /* CV64CONSOLE */
return (0);
/* Lets be Paranoid: Test man and prod id */
@@ -323,7 +410,7 @@ grfcvmatch(pdp, match, auxp)
cvcons_unit = cfp->cf_unit;
grfcv_cfdata = cfp;
}
-#endif
+#endif /* CV64CONSOLE */
return (1);
}
@@ -333,9 +420,10 @@ grfcvattach(pdp, dp, auxp)
struct device *pdp, *dp;
void *auxp;
{
- static struct grf_softc congrf;
+ static struct grf_cv_softc congrf;
struct zbus_args *zap;
struct grf_softc *gp;
+ struct grf_cv_softc *gcp;
static char attachflag = 0;
zap = auxp;
@@ -346,28 +434,32 @@ grfcvattach(pdp, dp, auxp)
*/
if (dp == NULL) /* console init */
- gp = &congrf;
+ gcp = &congrf;
else
- gp = (struct grf_softc *)dp;
+ gcp = (struct grf_cv_softc *)dp;
- if (dp != NULL && congrf.g_regkva != 0) {
+ gp = &gcp->gcs_sc;
+
+ if (dp != NULL && congrf.gcs_sc.g_regkva != 0) {
/*
* inited earlier, just copy (not device struct)
*/
printf("\n");
-#ifdef CV64CONSOLE
- bcopy(&congrf.g_display, &gp->g_display,
- (char *) &gp[1] - (char *) &gp->g_display);
-#else
- gp->g_regkva = (volatile caddr_t)cv_boardaddr + 0x02000000;
- gp->g_fbkva = (volatile caddr_t)cv_boardaddr + 0x01400000;
-
- gp->g_unit = GRF_CV64_UNIT;
- gp->g_mode = cv_mode;
- gp->g_conpri = grfcv_cnprobe();
- gp->g_flags = GF_ALIVE;
-#endif
+ bcopy(&congrf.gcs_sc.g_display, &gp->g_display,
+ (char *) &gcp->gcs_isr - (char *) &gp->g_display);
+
+ /* ... and transfer the isr */
+ gcp->gcs_isr.isr_ipl = CV_INT_NUM;
+#if CV_INT_NUM == 6
+ gcp->gcs_isr.isr_mapped_ipl = IPL_TTY;
+#endif /* CV_INT_NUM == 6 */
+ gcp->gcs_isr.isr_intr = cvintr;
+ gcp->gcs_isr.isr_arg = (void *)gp;
+
+ /* First add new isr */
+ add_isr(&gcp->gcs_isr);
+ remove_isr(&congrf.gcs_isr);
} else {
gp->g_regkva = (volatile caddr_t)cv_boardaddr + 0x02000000;
gp->g_fbkva = (volatile caddr_t)cv_boardaddr + 0x01400000;
@@ -377,13 +469,22 @@ grfcvattach(pdp, dp, auxp)
gp->g_conpri = grfcv_cnprobe();
gp->g_flags = GF_ALIVE;
+ /* add Interrupt Handler */
+ gcp->gcs_isr.isr_ipl = CV_INT_NUM;
+#if CV_INT_NUM == 6
+ gcp->gcs_isr.isr_mapped_ipl = IPL_TTY;
+#endif /* CV_INT_NUM == 6 */
+ gcp->gcs_isr.isr_intr = cvintr;
+ gcp->gcs_isr.isr_arg = (void *)gp;
+ add_isr(&gcp->gcs_isr);
+
/* wakeup the board */
cv_boardinit(gp);
#ifdef CV64CONSOLE
grfcv_iteinit(gp);
(void)cv_load_mon(gp, &cvconsole_mode);
-#endif
+#endif /* CV64CONSOLE */
}
/*
@@ -391,7 +492,8 @@ grfcvattach(pdp, dp, auxp)
*/
if (amiga_config_found(grfcv_cfdata, &gp->g_device, gp, grfcvprint)) {
if (dp != NULL)
- printf("grfcv: CyberVision64 with %dMB being used\n", cv_fbsize/0x100000);
+ printf("grfcv: CyberVision64 with %dMB being used\n",
+ cv_fbsize/0x100000);
attachflag = 1;
} else {
if (!attachflag)
@@ -421,7 +523,7 @@ grfcvprint(auxp, pnp)
* higher byte: Bits 0-6: M divider value for e.g. SR11 or SR13
*/
-static unsigned short
+unsigned short
cv_compute_clock(freq)
unsigned long freq;
{
@@ -492,6 +594,17 @@ cv_boardinit(gp)
WCrt(ba, CRT_ID_REGISTER_LOCK_1, 0x48); /* unlock S3 VGA regs */
WCrt(ba, CRT_ID_REGISTER_LOCK_2, 0xA5); /* unlock syscontrol */
+ /*
+ * The default board interrupt is #6.
+ * Set the roxxler register to use interrupt #2, not #6.
+ */
+#if CV_INT_NUM == 2
+ cv_write_port(0x8080, ba - 0x02000000);
+#endif /* CV_INT_NUM == 2 */
+
+ /* Enable board interrupts */
+ cv_write_port(0x8008, ba - 0x02000000);
+
test = RCrt(ba, CRT_ID_SYSTEM_CONFIG);
test = test | 0x01; /* enable enhaced register access */
test = test & 0xEF; /* clear bit 4, 0 wait state */
@@ -504,8 +617,8 @@ cv_boardinit(gp)
*/
vgaw(ba, ECR_ADV_FUNC_CNTL, 0x31);
- /* enable cpu acess, color mode, high 64k page */
- vgaw(ba, GREG_MISC_OUTPUT_W, 0x23);
+ /* enable color mode (bit0), cpu acess (bit1), high 64k page (bit5) */
+ vgaw(ba, GREG_MISC_OUTPUT_W, 0xe3);
/* Cpu base addr */
WCrt(ba, CRT_ID_EXT_SYS_CNTL_4, 0x00);
@@ -752,7 +865,6 @@ cv_getvmode(gp, vm)
/* adjust internal values to pixel values */
vm->hblank_start *= 8;
- vm->hblank_stop *= 8;
vm->hsync_start *= 8;
vm->hsync_stop *= 8;
vm->htotal *= 8;
@@ -812,11 +924,11 @@ cv_mode(gp, cmd, arg, a2, a3)
case GM_GRFOFF:
#ifndef CV64CONSOLE
- cvscreen(1, gp->g_regkva - 0x02000000)
-#else
+ cvscreen(1, gp->g_regkva - 0x02000000);
+#else /* !CV64CONSOLE */
cv_load_mon(gp, &cvconsole_mode);
ite_reinit(gp->g_itedev);
-#endif
+#endif /* !CV64CONSOLE */
return (0);
case GM_GRFCONFIG:
@@ -854,7 +966,7 @@ cv_ioctl (gp, cmd, data)
void *data;
{
switch (cmd) {
-#ifdef CV_HARDWARE_CURSOR
+#ifndef CV_NO_HARDWARE_CURSOR
case GRFIOCGSPRITEPOS:
return(cv_getspritepos (gp, (struct grf_position *) data));
@@ -869,14 +981,14 @@ cv_ioctl (gp, cmd, data)
case GRFIOCGSPRITEMAX:
return(cv_getspritemax (gp, (struct grf_position *) data));
-#else /* CV_HARDWARE_CURSOR */
+#else /* !CV_NO_HARDWARE_CURSOR */
case GRFIOCGSPRITEPOS:
case GRFIOCSSPRITEPOS:
case GRFIOCSSPRITEINF:
case GRFIOCGSPRITEINF:
case GRFIOCGSPRITEMAX:
break;
-#endif /* CV_HARDWARE_CURSOR */
+#endif /* !CV_NO_HARDWARE_CURSOR */
case GRFIOCGETCMAP:
return (cv_getcmap (gp, (struct grf_colormap *) data));
@@ -915,7 +1027,6 @@ cv_setmonitor(gp, gv)
if (gv->mode_num == 255) {
bcopy(gv, &cvconsole_mode.gv, sizeof(struct grfvideo_mode));
cvconsole_mode.gv.hblank_start /= 8;
- cvconsole_mode.gv.hblank_stop /= 8;
cvconsole_mode.gv.hsync_start /= 8;
cvconsole_mode.gv.hsync_stop /= 8;
cvconsole_mode.gv.htotal /= 8;
@@ -936,7 +1047,7 @@ cv_setmonitor(gp, gv)
*/
if (gp->g_flags & GF_GRFON)
if (md == monitor_current) {
- printf("grf_cv: Changing the used mode not allowed!\n");
+ printf("grfcv: Changing the used mode not allowed!\n");
return (EINVAL);
}
@@ -945,7 +1056,6 @@ cv_setmonitor(gp, gv)
/* adjust pixel oriented values to internal rep. */
md->hblank_start /= 8;
- md->hblank_stop /= 8;
md->hsync_start /= 8;
md->hsync_stop /= 8;
md->htotal /= 8;
@@ -1091,13 +1201,13 @@ cv_mondefok(gv)
#endif
break;
default:
- printf("grf_cv: Illegal depth in mode %d\n",
+ printf("grfcv: Illegal depth in mode %d\n",
(int) gv->mode_num);
return (0);
}
if (gv->pixel_clock > maxpix) {
- printf("grf_cv: Pixelclock too high in mode %d\n",
+ printf("grfcv: Pixelclock too high in mode %d\n",
(int) gv->mode_num);
return (0);
}
@@ -1112,6 +1222,11 @@ cv_mondefok(gv)
}
}
+ if (gv->disp_flags & GRF_FLAGS_SYNC_ON_GREEN) {
+ printf("grfcv: sync-on-green is not supported\n");
+ return (0);
+ }
+
return (1);
}
@@ -1127,12 +1242,13 @@ cv_load_mon(gp, md)
unsigned short mnr;
unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS,
VSE, VT;
- char LACE, DBLSCAN, TEXT, CONSOLE;
- int uplim, lowlim;
int cr50, sr15, sr18, clock_mode, test;
int m, n; /* For calc'ing display FIFO */
int tfillm, temptym; /* FIFO fill and empty mclk's */
int hmul; /* Multiplier for hor. Values */
+ unsigned char hvsync_pulse;
+ char TEXT, CONSOLE;
+
/* identity */
gv = &md->gv;
@@ -1140,13 +1256,18 @@ cv_load_mon(gp, md)
CONSOLE = (gv->mode_num == 255);
if (!cv_mondefok(gv)) {
- printf("grfcv: The monitor definition is illegal.\n");
- printf("grfcv: See the manpage of grfconfig for more informations\n");
+ printf("grfcv: Monitor definition not ok\n");
return (0);
}
+
ba = gp->g_regkva;
fb = gp->g_fbkva;
+ /* Disable Interrupts */
+ test = RCrt(ba, CRT_ID_BACKWAD_COMP_1);
+ test &= ~0x10;
+ WCrt(ba, CRT_ID_BACKWAD_COMP_1, test);
+
/* turn gfx off, don't mess up the display */
gfx_on_off(1, ba);
@@ -1171,24 +1292,24 @@ cv_load_mon(gp, md)
/* get display mode parameters */
switch (gv->depth) {
- case 15:
- case 16:
- hmul = 2;
- break;
- default:
- hmul = 1;
- break;
+ case 15:
+ case 16:
+ hmul = 2;
+ break;
+ default:
+ hmul = 1;
+ break;
}
HBS = gv->hblank_start * hmul;
- HBE = gv->hblank_stop * hmul;
HSS = gv->hsync_start * hmul;
HSE = gv->hsync_stop * hmul;
- HT = gv->htotal*hmul - 5;
+ HBE = gv->htotal * hmul - 6;
+ HT = gv->htotal * hmul - 5;
VBS = gv->vblank_start - 1;
VSS = gv->vsync_start;
VSE = gv->vsync_stop;
- VBE = gv->vblank_stop;
+ VBE = gv->vtotal - 3;
VT = gv->vtotal - 2;
/* Disable enhanced Mode for text display */
@@ -1201,17 +1322,36 @@ cv_load_mon(gp, md)
HDE = (gv->disp_width + 3) * hmul / 8 - 1; /*HBS;*/
VDE = gv->disp_height - 1;
- /* figure out whether lace or dblscan is needed */
-
- uplim = gv->disp_height + (gv->disp_height / 4);
- lowlim = gv->disp_height - (gv->disp_height / 4);
- LACE = (((VT * 2) > lowlim) && ((VT * 2) < uplim)) ? 1 : 0;
- DBLSCAN = (((VT / 2) > lowlim) && ((VT / 2) < uplim)) ? 1 : 0;
-
/* adjustments */
+ if (gv->disp_flags & GRF_FLAGS_LACE) {
+ VDE = VDE / 2;
+ VBS = VBS / 2;
+ VSS = VSS / 2;
+ VSE = VSE / 2;
+ VBE = VBE / 2;
+ VT = VT / 2;
+ }
- if (LACE)
- VDE /= 2;
+ /* Horizontal/Vertical Sync Pulse */
+ /*
+ * GREG_MISC_OUTPUT_W Register:
+ * bit description (0/1)
+ * 0 Monochrome/Color emulation
+ * 1 Disable/Enable access of the display memory from the CPU
+ * 5 Select the low/high 64K page of memory
+ * 6 Select a positive/negative horizontal retrace sync pulse
+ * 7 Select a positive/negative vertical retrace sync pulse
+ */
+ hvsync_pulse = vgar(ba, GREG_MISC_OUTPUT_R);
+ if (gv->disp_flags & GRF_FLAGS_PHSYNC)
+ hvsync_pulse &= ~0x40;
+ else
+ hvsync_pulse |= 0x40;
+ if (gv->disp_flags & GRF_FLAGS_PVSYNC)
+ hvsync_pulse &= ~0x80;
+ else
+ hvsync_pulse |= 0x80;
+ vgaw(ba, GREG_MISC_OUTPUT_W, hvsync_pulse);
/* GFX hardware cursor off */
WCrt(ba, CRT_ID_HWGC_MODE, 0x00);
@@ -1269,7 +1409,7 @@ cv_load_mon(gp, md)
WCrt(ba, CRT_ID_MAX_SCAN_LINE,
0x40 | /* TEXT ? 0x00 ??? */
- (DBLSCAN ? 0x80 : 0x00) |
+ ((gv->disp_flags & GRF_FLAGS_DBLSCAN) ? 0x80 : 0x00) |
((VBS & 0x200) ? 0x20 : 0x00) |
(TEXT ? ((md->fy - 1) & 0x1f) : 0x00));
@@ -1278,13 +1418,13 @@ cv_load_mon(gp, md)
/* text cursor */
if (TEXT) {
-#if 1
+#if CV_ULCURSOR
WCrt(ba, CRT_ID_CURSOR_START, (md->fy & 0x1f) - 2);
WCrt(ba, CRT_ID_CURSOR_END, (md->fy & 0x1f) - 1);
-#else
+#else /* CV_ULCURSOR */
WCrt(ba, CRT_ID_CURSOR_START, 0x00);
WCrt(ba, CRT_ID_CURSOR_END, md->fy & 0x1f);
-#endif
+#endif /* CV_ULCURSOR */
WCrt(ba, CRT_ID_UNDERLINE_LOC, (md->fy - 1) & 0x1f);
WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
@@ -1302,7 +1442,8 @@ cv_load_mon(gp, md)
WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
WCrt(ba, CRT_ID_LACE_RETR_START, HT / 2);
- WCrt(ba, CRT_ID_LACE_CONTROL, (LACE ? 0x20 : 0x00));
+ WCrt(ba, CRT_ID_LACE_CONTROL,
+ ((gv->disp_flags & GRF_FLAGS_LACE) ? 0x20 : 0x00));
WGfx(ba, GCT_ID_GRAPHICS_MODE,
((TEXT || (gv->depth == 1)) ? 0x00 : 0x40));
@@ -1318,9 +1459,9 @@ cv_load_mon(gp, md)
WCrt(ba, CRT_ID_BACKWAD_COMP_2, (test | 0x20));
sr15 = RSeq(ba, SEQ_ID_CLKSYN_CNTL_2);
- sr15 &= 0xef;
+ sr15 &= ~0x10;
sr18 = RSeq(ba, SEQ_ID_RAMDAC_CNTL);
- sr18 &= 0x7f;
+ sr18 &= ~0x80;
clock_mode = 0x00;
cr50 = 0x00;
@@ -1471,12 +1612,28 @@ cv_load_mon(gp, md)
}
}
- /* Some kind of Magic */
+ /* Set display enable flag */
WAttr(ba, 0x33, 0);
/* turn gfx on again */
gfx_on_off(0, ba);
+ /* enable interrupts */
+ test = RCrt(ba, CRT_ID_BACKWAD_COMP_1);
+ test |= 0x10;
+ WCrt(ba, CRT_ID_BACKWAD_COMP_1, test);
+
+ test = RCrt(ba, CRT_ID_END_VER_RETR);
+ test &= ~0x20;
+ WCrt(ba, CRT_ID_END_VER_RETR, test);
+ test &= ~0x10;
+ WCrt(ba, CRT_ID_END_VER_RETR, test);
+ test |= 0x10;
+ WCrt(ba, CRT_ID_END_VER_RETR, test);
+#ifndef CV_NO_HARDWARE_CURSOR
+ cv_setup_hwc(gp);
+#endif
+
/* Pass-through */
cvscreen(0, ba - 0x02000000);
@@ -1539,7 +1696,7 @@ cv_inittextmode(gp)
}
-static inline void
+static __inline void
cv_write_port(bits, BoardAddr)
unsigned short bits;
volatile caddr_t BoardAddr;
@@ -1566,7 +1723,7 @@ cv_write_port(bits, BoardAddr)
* 1 = Amiga Signal,
* ba = boardaddr
*/
-static inline void
+static __inline void
cvscreen(toggle, ba)
int toggle;
volatile caddr_t ba;
@@ -1581,7 +1738,7 @@ cvscreen(toggle, ba)
/* 0 = on, 1= off */
/* ba= registerbase */
-static inline void
+static __inline void
gfx_on_off(toggle, ba)
int toggle;
volatile caddr_t ba;
@@ -1592,46 +1749,55 @@ gfx_on_off(toggle, ba)
toggle = toggle << 5;
r = RSeq(ba, SEQ_ID_CLOCKING_MODE);
- r &= 0xdf; /* set Bit 5 to 0 */
+ r &= ~0x20; /* set Bit 5 to 0 */
WSeq(ba, SEQ_ID_CLOCKING_MODE, r | toggle);
}
-
-#ifdef CV_HARDWARE_CURSOR
+#ifndef CV_NO_HARDWARE_CURSOR
static unsigned char cv_hotx = 0, cv_hoty = 0;
+static char cv_cursor_on = 0;
/* Hardware Cursor handling routines */
int
-cv_getspritepos (gp, pos)
+cv_getspritepos(gp, pos)
struct grf_softc *gp;
struct grf_position *pos;
{
int hi,lo;
volatile caddr_t ba = gp->g_regkva;
- hi = RCrt (ba, CRT_ID_HWGC_ORIGIN_Y_HI);
- lo = RCrt (ba, CRT_ID_HWGC_ORIGIN_Y_LO);
+ hi = RCrt(ba, CRT_ID_HWGC_ORIGIN_Y_HI);
+ lo = RCrt(ba, CRT_ID_HWGC_ORIGIN_Y_LO);
pos->y = (hi << 8) + lo;
- hi = RCrt (ba, CRT_ID_HWGC_ORIGIN_X_HI);
- lo = RCrt (ba, CRT_ID_HWGC_ORIGIN_X_LO);
+ hi = RCrt(ba, CRT_ID_HWGC_ORIGIN_X_HI);
+ lo = RCrt(ba, CRT_ID_HWGC_ORIGIN_X_LO);
pos->x = (hi << 8) + lo;
return (0);
}
-
int
-cv_setspritepos (gp, pos)
+cv_setspritepos(gp, pos)
struct grf_softc *gp;
struct grf_position *pos;
{
volatile caddr_t ba = gp->g_regkva;
- short x = pos->x, y = pos->y;
+ short x, y;
+ static short savex, savey;
short xoff, yoff;
+ if (pos) {
+ x = pos->x;
+ y = pos->y;
+ savex = x;
+ savey= y;
+ } else { /* restore cursor */
+ x = savex;
+ y = savey;
+ }
x -= cv_hotx;
y -= cv_hoty;
if (x < 0) {
@@ -1648,37 +1814,26 @@ cv_setspritepos (gp, pos)
yoff = 0;
}
- WCrt (ba, CRT_ID_HWGC_ORIGIN_X_HI, (x >> 8));
- WCrt (ba, CRT_ID_HWGC_ORIGIN_X_LO, (x & 0xff));
+ WCrt(ba, CRT_ID_HWGC_ORIGIN_X_HI, (x >> 8));
+ WCrt(ba, CRT_ID_HWGC_ORIGIN_X_LO, (x & 0xff));
- WCrt (ba, CRT_ID_HWGC_ORIGIN_Y_LO, (y & 0xff));
- WCrt (ba, CRT_ID_HWGC_DSTART_X, xoff);
- WCrt (ba, CRT_ID_HWGC_DSTART_Y, yoff);
- WCrt (ba, CRT_ID_HWGC_ORIGIN_Y_HI, (y >> 8));
+ WCrt(ba, CRT_ID_HWGC_ORIGIN_Y_LO, (y & 0xff));
+ WCrt(ba, CRT_ID_HWGC_DSTART_X, xoff);
+ WCrt(ba, CRT_ID_HWGC_DSTART_Y, yoff);
+ WCrt(ba, CRT_ID_HWGC_ORIGIN_Y_HI, (y >> 8));
- return(0);
+ return (0);
}
-static inline short
-M2I(short val) {
- asm volatile (" rorw #8,%0 ; \
- swap %0 ; \
- rorw #8,%0 ; " : "=d" (val) : "0" (val));
- return (val);
+static __inline short
+M2I(val)
+ short val;
+{
+ return (((val & 0xff00) >> 8) | ((val & 0xff) << 8));
}
-#define M2INS(val) \
- asm volatile (" rorw #8,%0 ; \
- swap %0 ; \
- rorw #8,%0 ; \
- swap %0 ; " : "=d" (val) : "0" (val));
-
-#define HWC_OFF (cv_fbsize - 1024*2)
-#define HWC_SIZE 1024
-
-
int
-cv_getspriteinfo (gp, info)
+cv_getspriteinfo(gp, info)
struct grf_softc *gp;
struct grf_spriteinfo *info;
{
@@ -1728,40 +1883,52 @@ cv_getspriteinfo (gp, info)
void
-cv_setup_hwc (gp, col1, col2, hsx, hsy, data)
+cv_setup_hwc(gp)
struct grf_softc *gp;
- unsigned char col1;
- unsigned char col2;
- unsigned char hsx;
- unsigned char hsy;
- const unsigned long *data;
{
volatile caddr_t ba = gp->g_regkva;
- unsigned long *c = (unsigned long *)(gp->g_fbkva + HWC_OFF);
- const unsigned long *s = data;
+ volatile caddr_t hwc;
int test;
- short x = (HWC_SIZE / (4*4)) - 1;
- /* copy only, if there is a data pointer. */
- if (data) do {
- *c++ = *s++;
- *c++ = *s++;
- *c++ = *s++;
- *c++ = *s++;
- } while (x-- > 0);
+ if (gp->g_display.gd_planes <= 4)
+ cv_cursor_on = 0; /* don't enable hwc in text modes */
+ if (cv_cursor_on == 0)
+ return;
/* reset colour stack */
+#if 0
test = RCrt(ba, CRT_ID_HWGC_MODE);
- asm volatile("nop");
- WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
- WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
+ __asm volatile ("nop");
+#else
+ /* do it in assembler, the above does't seem to work */
+ __asm volatile ("moveb #0x45, %1@(0x3d4); moveb %1@(0x3d5),%0" :
+ "=r" (test) : "a" (ba));
+#endif
+
WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
+ hwc = ba + CRT_ADDRESS_W;
+ *hwc = 0;
+ *hwc = 0;
+
+#if 0
test = RCrt(ba, CRT_ID_HWGC_MODE);
- asm volatile("nop");
- WCrt (ba, CRT_ID_HWGC_BG_STACK, 0x1);
- WCrt (ba, CRT_ID_HWGC_BG_STACK, 0x1);
- WCrt (ba, CRT_ID_HWGC_BG_STACK, 0x1);
+ __asm volatile ("nop");
+#else
+ /* do it in assembler, the above does't seem to work */
+ __asm volatile ("moveb #0x45, %1@(0x3d4); moveb %1@(0x3d5),%0" :
+ "=r" (test) : "a" (ba));
+#endif
+ switch (gp->g_display.gd_planes) {
+ case 8:
+ WCrt(ba, CRT_ID_HWGC_BG_STACK, 0x1);
+ *hwc = 1;
+ break;
+ default:
+ WCrt(ba, CRT_ID_HWGC_BG_STACK, 0xff);
+ *hwc = 0xff;
+ *hwc = 0xff;
+ }
test = HWC_OFF / HWC_SIZE;
WCrt (ba, CRT_ID_HWGC_START_AD_HI, (test >> 8));
@@ -1770,14 +1937,21 @@ cv_setup_hwc (gp, col1, col2, hsx, hsy, data)
WCrt (ba, CRT_ID_HWGC_DSTART_X , 0);
WCrt (ba, CRT_ID_HWGC_DSTART_Y , 0);
- WCrt (ba, CRT_ID_EXT_DAC_CNTL, 0x10); /* Cursor X11 Mode */
+ WCrt (ba, CRT_ID_EXT_DAC_CNTL, 0x10); /* Cursor X11 Mode */
+ /*
+ * Put it into Windoze Mode or you'll see sometimes a white stripe
+ * on the right side (in double clocking modes with a screen bigger
+ * > 1023 pixels).
+ */
+ WCrt (ba, CRT_ID_EXT_DAC_CNTL, 0x00); /* Cursor Windoze Mode */
WCrt (ba, CRT_ID_HWGC_MODE, 0x01);
}
-
-/* This is the reason why you shouldn't use the HGC in the Kernel:( */
-
+/*
+ * This was the reason why you shouldn't use the HWC in the Kernel:(
+ * Obsoleted now by use of interrupts :-)
+ */
#define VerticalRetraceWait(ba) \
{ \
while (vgar(ba, GREG_INPUT_STATUS1_R) == 0x00) ; \
@@ -1809,6 +1983,7 @@ cv_setspriteinfo (gp, info)
u_char *imp, *mp;
unsigned short row;
+#ifdef CV_NO_INT
/* Cursor off */
WCrt (ba, CRT_ID_HWGC_MODE, 0x00);
@@ -1827,6 +2002,10 @@ cv_setspriteinfo (gp, info)
* (thanks to Harald Koenig for this tip!)
*/
+ /*
+ * Remark 06/06/96: Update in interrupt obsoletes this,
+ * but the warning should stay there!
+ */
VerticalRetraceWait(ba);
WCrt (ba, CRT_ID_HWGC_ORIGIN_X_HI, 0x7);
@@ -1835,6 +2014,7 @@ cv_setspriteinfo (gp, info)
WCrt (ba, CRT_ID_HWGC_DSTART_X, 0x3f);
WCrt (ba, CRT_ID_HWGC_DSTART_Y, 0x3f);
WCrt (ba, CRT_ID_HWGC_ORIGIN_Y_HI, 0x7);
+#endif /* CV_NO_INT */
if (info->size.y > 64)
info->size.y = 64;
@@ -1849,11 +2029,14 @@ cv_setspriteinfo (gp, info)
copyin(info->image, image, info->size.y * info->size.x / 8);
copyin(info->mask, mask, info->size.y * info->size.x / 8);
- hwp = (u_short *)(fb +HWC_OFF);
+#ifdef CV_NO_INT
+ hwp = (u_short *)(fb + HWC_OFF);
/* This is necessary in order not to crash the board */
-
VerticalRetraceWait(ba);
+#else /* CV_NO_INT */
+ hwp = (u_short *) cv_cursor_storage;
+#endif /* CV_NO_INT */
/*
* setting it is slightly more difficult, because we can't
@@ -1865,28 +2048,33 @@ cv_setspriteinfo (gp, info)
row < info->size.y; row++) {
u_short im1, im2, im3, im4, m1, m2, m3, m4;
- im1 = *(unsigned short *)imp;
- imp += 2;
- m1 = *(unsigned short *)mp;
+ m1 = ~(*(unsigned short *)mp);
+ im1 = *(unsigned short *)imp & *(unsigned short *)mp;
mp += 2;
-
- im2 = *(unsigned short *)imp;
imp += 2;
- m2 = *(unsigned short *)mp;
+
+ m2 = ~(*(unsigned short *)mp);
+ im2 = *(unsigned short *)imp & *(unsigned short *)mp;
mp += 2;
+ imp += 2;
if (info->size.x > 32) {
- im3 = *(unsigned long *)imp;
- imp += 4;
- m3 = *(unsigned long *)mp;
- mp += 4;
- im4 = *(unsigned long *)imp;
- imp += 4;
- m4 = *(unsigned long *)mp;
- mp += 4;
+ m3 = ~(*(unsigned short *)mp);
+ im3 = *(unsigned short *)imp &
+ *(unsigned short *)mp;
+ mp += 2;
+ imp += 2;
+ m4 = ~(*(unsigned short *)mp);
+ im4 = *(unsigned short *)imp &
+ *(unsigned short *)mp;
+ mp += 2;
+ imp += 2;
+ } else {
+ m3 = 0xffff;
+ im3 = 0;
+ m4 = 0xffff;
+ im4 = 0;
}
- else
- im3 = m3 = im4 = m4 = 0;
switch (depth) {
case 8:
@@ -1923,68 +2111,100 @@ cv_setspriteinfo (gp, info)
break;
}
}
- for (; row < 64; row++) {
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
+
+ if (depth < 24) {
+ for (; row < 64; row++) {
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ }
+ } else {
+ for (; row < 64; row++) {
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ }
}
+
free(image, M_TEMP);
- cv_setup_hwc(gp, 1, 0, 0, 0, NULL);
+ /* cv_setup_hwc(gp); */
cv_hotx = info->hot.x;
cv_hoty = info->hot.y;
+#ifdef CV_NO_INT
/* One must not write twice per vertical blank :-( */
- /* VerticalRetraceWait(ba); */
-
+ VerticalRetraceWait(ba);
cv_setspritepos (gp, &info->pos);
+#else /* CV_NO_INT */
+ cv_setspritepos (gp, &info->pos);
+ curs_update_flag = 1;
+#endif /* CV_NO_INT */
}
if (info->set & GRFSPRSET_CMAP) {
+ volatile caddr_t hwc;
int test;
- VerticalRetraceWait(ba);
-
/* reset colour stack */
test = RCrt(ba, CRT_ID_HWGC_MODE);
asm volatile("nop");
switch (depth) {
- case 32:
- case 24:
- WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
- case 16:
- case 8:
- /* info->cmap.green[1] */
+ case 8:
+ case 15:
+ case 16:
WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
+ hwc = ba + CRT_ADDRESS_W;
+ *hwc = 0;
+ break;
+ case 32:
+ case 24:
WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
+ hwc = ba + CRT_ADDRESS_W;
+ *hwc = 0;
+ *hwc = 0;
+ break;
}
test = RCrt(ba, CRT_ID_HWGC_MODE);
asm volatile("nop");
switch (depth) {
- case 8:
- WCrt (ba, CRT_ID_HWGC_BG_STACK, 1);
+ case 8:
WCrt (ba, CRT_ID_HWGC_BG_STACK, 1);
+ hwc = ba + CRT_ADDRESS_W;
+ *hwc = 1;
break;
- case 32: case 24:
- WCrt (ba, CRT_ID_HWGC_BG_STACK, 0xff);
- case 16:
+ case 15:
+ case 16:
WCrt (ba, CRT_ID_HWGC_BG_STACK, 0xff);
+ hwc = ba + CRT_ADDRESS_W;
+ *hwc = 0xff;
+ break;
+ case 32:
+ case 24:
WCrt (ba, CRT_ID_HWGC_BG_STACK, 0xff);
+ hwc = ba + CRT_ADDRESS_W;
+ *hwc = 0xff;
+ *hwc = 0xff;
+ break;
}
}
if (info->set & GRFSPRSET_ENABLE) {
-#if 0
- if (info->enable)
- control = 0x85;
- else
- control = 0;
- WSeq(ba, SEQ_ID_CURSOR_CONTROL, control);
-#endif
+ if (info->enable) {
+ cv_cursor_on = 1;
+ cv_setup_hwc(gp);
+ /* WCrt(ba, CRT_ID_HWGC_MODE, 0x01); */
+ } else
+ WCrt(ba, CRT_ID_HWGC_MODE, 0x00);
}
if (info->set & GRFSPRSET_POS)
cv_setspritepos(gp, &info->pos);
@@ -2009,6 +2229,6 @@ cv_getspritemax (gp, pos)
return(0);
}
-#endif /* CV_HARDWARE_CURSOR */
+#endif /* CV_NO_HARDWARE_CURSOR */
#endif /* NGRFCV */