Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!mips!wrdis01!nstn.ns.ca!uupsi!sunic!fuug!demos!relcom!vak From: vak@relcom.kiae.su (Serge Vakulenko) Newsgroups: comp.unix.sysv386 Subject: Re: PVGA on X386-1.1a Keywords: X386 Message-ID: <1991Mar22.135827.14750@relcom.kiae.su> Date: 22 Mar 91 13:58:27 GMT References: <1991Mar13.173923.18698@colorado.edu> Organization: Kurchatov Institute of Atomic Energy, Moscow, USSR Lines: 434 In <1991Mar13.173923.18698@colorado.edu> jennings@cs.Colorado.EDU (Jeff Jennings) writes: >My friend is trying to run the X386 server on his Interactive machine with >a Paradise OEM card. In Roell's announcement he says PVGA support is one of >the new features of this release. My friend gets the same behavior as before, >that is, a series of images (4 or 5) running from the lower left to upper >right on his screen. So he gets several images of the same xterm, several >mouse cursors that all move together, etc. Has anyone been able to make this >work with a PVGA card? From what he described, I think he installed it >correctly, although I haven't checked his machine personally to make sure. >Thanks for any help or info. Here is corecct driver for PVGA1A. It works well on Western Digital and Paradise chip sets. Place it in directory mit/server/ddx/at386/vga/pvga1a, then rebuild server. Please, send all questions to Serge Vakulenko, . #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh Imakefile <<'END_OF_Imakefile' X#include X XSRCS = driver.c bank.s X XOBJS = driver.o bank.o X XINCLUDES = -I. -I.. -I../.. -I../../../mfb -I../../../mi \ X -I../../../../include -I$(INCLUDESRC) X X#if DebugServer && ProfileServer XDebuggedAndProfiledLibraryObjectRule() X#else X# if DebugServer XDebuggedLibraryObjectRule() X# else X# if ProfileServer XProfiledLibraryObjectRule() X# else XNormalLibraryObjectRule() X# endif X# endif X#endif X X XNormalRelocatableTarget(Driver, $(OBJS)) X XDependTarget() X END_OF_Imakefile if test 470 -ne `wc -c driver.c <<'END_OF_driver.c' X/* X * Copyright 1990 by Thomas Roell, Dinkelscherben, Germany. X * X * Permission to use, copy, modify, distribute, and sell this software and its X * documentation for any purpose is hereby granted without fee, provided that X * the above copyright notice appear in all copies and that both that X * copyright notice and this permission notice appear in supporting X * documentation, and that the name of Thomas Roell not be used in X * advertising or publicity pertaining to distribution of the software without X * specific, written prior permission. Thomas Roell makes no representations X * about the suitability of this software for any purpose. It is provided X * "as is" without express or implied warranty. X * X * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO X * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR X * PERFORMANCE OF THIS SOFTWARE. X * X * Author: Thomas Roell, roell@lan.informatik.tu-muenchen.de X * X * $Header: /proj/X11/mit/server/ddx/at386/vga/pvga1a/RCS/driver.c,v 1.4 90/12/16 19:07:18 root Exp $ X */ X X X#include "X386.h" X#include "vga.h" X Xtypedef struct { X vgaHWRec std; /* std IBM VGA register */ X unchar PR0A; /* paradise special */ X unchar PR0B; X unchar PR1; X unchar PR2; X unchar PR3; X unchar PR4; X unchar PR5; X unchar Clock1; X unchar Clock2; X } vgaPVGA1ARec, *vgaPVGA1APtr; X Xstatic void PVGA1AInit(); Xstatic void * PVGA1ASave(); Xstatic void PVGA1ARestore(); Xstatic void PVGA1AAdjust(); Xextern void PVGA1ASetRead(); Xextern void PVGA1ASetWrite(); Xextern void PVGA1ASetReadWrite(); X X XvgaVideoChipRec PVGA1A = { X PVGA1AInit, X PVGA1ASave, X PVGA1ARestore, X PVGA1AAdjust, X PVGA1ASetRead, X PVGA1ASetWrite, X PVGA1ASetReadWrite, X 0x10000, X 0x08000, X 15, X 0x7FFF, X 0x00000, 0x08000, X 0x08000, 0x10000, X}; X X X/* X *----------------------------------------------------------------------- X * PVGA1ARestore -- X * restore a video mode X * X * Results: X * nope. X * X * Side Effects: X * the display enters a new graphics mode. X * X *----------------------------------------------------------------------- X */ Xvoid XPVGA1ARestore(restore) X vgaPVGA1APtr restore; X{ X TRACE( ("PVGA1ARestore(restore=0x%x)\n",restore) ); X X outb(0x3CE, 0x0F); outb(0x3CF, 0x05); /* unlock paradises special */ X outb(0x3CE, 0x0D); outb(0x3CF, 0x00); X outb(0x3CE, 0x09); outb(0x3CF, 0x00); /* segment select */ X outb(0x3CE, 0x0A); outb(0x3CF, 0x00); /* segment select */ X X vgaHWRestore(restore); X X outb(0x3CE, 0x0F); outb(0x3CF, 0x05); /* unlock paradises special */ X outb(0x3CE, 0x09); outb(0x3CF, restore->PR0A); X outb(0x3CE, 0x0a); outb(0x3CF, restore->PR0B); X outb(0x3CE, 0x0b); outb(0x3CF, restore->PR1); X outb(0x3CE, 0x0c); outb(0x3CF, restore->PR2); X outb(0x3CE, 0x0d); outb(0x3CF, restore->PR3); X outb(0x3CE, 0x0e); outb(0x3CF, restore->PR4); X outb(0x3CE, 0x0f); outb(0x3CF, restore->PR5); X X outb(0x3d4, 0x2d); outb(0x3d5, restore->Clock1); X outb(0x3d4, 0x2e); outb(0x3d5, restore->Clock2); X outb(0x3d4, 0x2f); outb(0x3d5, 0); /* unlock some important register */ X X outb(0x3C4, 0x00); outb(0x3C5, 0x03); /* now reenable the timing sequencer */ X} X X/* X *----------------------------------------------------------------------- X * PVGA1ASave -- X * save the current video mode X * X * Results: X * pointer to the current mode record. X * X * Side Effects: X * None. X *----------------------------------------------------------------------- X */ Xvoid * XPVGA1ASave(save) X vgaPVGA1APtr save; X{ X unchar areg, breg; X X TRACE( ("PVGA1ASave(save=0x%x)\n",save) ); X X outb(0x3CE, 0x0F); outb(0x3CF, 0x05); /* unlock paradises special */ X outb(0x3CE, 0x0D); outb(0x3CF, 0x00); X outb(0x3CE, 0x09); areg = inb(0x3CF); X outb(0x3CE, 0x0A); breg = inb(0x3CF); X outb(0x3CE, 0x09); outb(0x3CF, 0x00); /* segment select */ X outb(0x3CE, 0x0A); outb(0x3CF, 0x00); /* segment select */ X X save = (vgaPVGA1APtr)vgaHWSave(save, sizeof(vgaPVGA1ARec)); X X save->PR0A = areg; X save->PR0B = breg; X outb(0x3CE, 0x0F); outb(0x3CF, 0x05); /* unlock paradises special */ X outb(0x3CE, 0x0B); save->PR1 = inb(0x3CF); X outb(0x3CE, 0x0C); save->PR2 = inb(0x3CF); X outb(0x3CE, 0x0E); save->PR4 = inb(0x3CF); X save->PR3 = 0x00; X save->PR5 = 0x05; X X outb(0x3d4, 0x2d); save->Clock1 = inb(0x3d5); X outb(0x3d4, 0x2e); save->Clock2 = inb(0x3d5); X X return ((void *) save); X} X X X/* X *----------------------------------------------------------------------- X * PVGA1AInit -- X * Handle the initialization, etc. of a screen. X * X * Results: X * pointer to the new mode record. X * X * Side Effects: X * X *----------------------------------------------------------------------- X */ Xvoid XPVGA1AInit(mode) X vgaModePtr mode; X{ X TRACE( ("PVGA1AInit(mode=0x%x)\n",mode) ); X X#define new ((vgaPVGA1APtr)vgaNewVideoState) X X vgaHWInit(mode,sizeof(vgaPVGA1ARec)); X X new->std.CRTC[19] = X386Screen.VirtualX >> 3; /* we are in byte-mode ... */ X new->std.CRTC[20] = 0x40; X new->std.CRTC[23] = 0xE3; /* thats what the man says */ X new->std.Graphics[6] = 5; X new->PR0A = 0x00; X new->PR0B = 0x00; X new->PR1 = 0x8e; X new->PR2 = 0x00; X new->PR3 = 0x00; X new->PR4 = 0x01; X new->PR5 = 0x05; X X new->Clock1 = (new->std.NoClock & 4) ? 0x20 : 0; X new->Clock2 = (new->std.NoClock & 8) ? 0x10 : 0; X X#ifdef notdef X { X int i; X X ErrorF("Misc(%2x)\n",new->std.MiscOutReg); X ErrorF("CRTC\n"); X for (i=0; i<25; i++) ErrorF("%2x, ",new->std.CRTC[i]); X ErrorF("\n\nSequencer\n"); X for (i=0; i<5; i++) ErrorF("%2x, ",new->std.Sequencer[i]); X ErrorF("\n\nGraphics\n"); X for (i=0; i<9; i++) ErrorF("%2x, ",new->std.Graphics[i]); X ErrorF("\n\nAttribute\n"); X for (i=0; i<21; i++) ErrorF("%2x, ",new->std.Attribute[i]); X ErrorF("\n\n\n"); X } X#endif X X} X X X/* X *----------------------------------------------------------------------- X * PVGA1AAdjust -- X * adjust the current video frame to display the mousecursor X * X * Results: X * nope. X * X * Side Effects: X * the display scrolls X *----------------------------------------------------------------------- X */ Xvoid XPVGA1AAdjust() X{ X int Base; X unchar temp; X X TRACE( ("PVGA1AAdjust()\n") ); X X Base = (X386Screen.FrameY0 * X386Screen.VirtualX +X386Screen.FrameX0) >>2; X X outb(vgaIOBase + 0x04, 0x0C); outb(vgaIOBase + 0x05, (Base & 0x00FF00) >>8); X outb(vgaIOBase + 0x04, 0x0D); outb(vgaIOBase + 0x05, Base & 0x00FF); X outb(0x3CE, 0x0D); temp=inb(0x3CF); X outb(0x3CF, ((Base & 0x030000) >> 13) | (temp & 0xE7)); X} END_OF_driver.c if test 6835 -ne `wc -c bank.s <<'END_OF_bank.s' X/* X * Copyright 1990 by Thomas Roell, Dinkelscherben, Germany. X * X * Permission to use, copy, modify, distribute, and sell this software and its X * documentation for any purpose is hereby granted without fee, provided that X * the above copyright notice appear in all copies and that both that X * copyright notice and this permission notice appear in supporting X * documentation, and that the name of Thomas Roell not be used in X * advertising or publicity pertaining to distribution of the software without X * specific, written prior permission. Thomas Roell makes no representations X * about the suitability of this software for any purpose. It is provided X * "as is" without express or implied warranty. X * X * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO X * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR X * PERFORMANCE OF THIS SOFTWARE. X * X * Author: Thomas Roell, roell@lan.informatik.tu-muenchen.de X * X * $Header: /proj/X11/mit/server/ddx/at386/vga/pvga1a/RCS/bank.s,v 1.4 90/12/16 19:07:15 root Exp $ X */ X X X/* X * These are here the very lowlevel VGA bankswitching routines. X * The segment to switch to is passed via %eax. Only %eax and %edx my be used X * without saving the original contents. X * X * WHY ASSEMBLY LANGUAGE ??? X * X * These routines must be callable by other assembly routines. But I don't X * want to have the overhead of pushing and poping the normal stack-frame. X */ X X/* X * what happens really here ? X * X * PRA and PRB are segmentpointers to out two segments. They have a granularity X * of 4096. That means we have to multiply the segmentnumber with 16, if we are X * working with 64k segment. But since PRA and PRB are 'indexed' registers, the X * index must be emitted first. This is accomplished by loading %al with the X * index and %ah with the value. Therefor we must shift the logical segment- X * number by 12. X * Another quirk is PRB. It's physical VGA mapping starts at 0xA0000, but it is X * only visible starting form 0xB0000 to 0xBFFFF. That means PRB has to be X * loaded with a value that points to the previous logical segment. X */ X X .text X X/* X * for ReadWrite operations, we are using only PR0A as pointer to a 32k X * window. X */ X .align 4 X .globl PVGA1ASetReadWrite XPVGA1ASetReadWrite: X decl %eax X shll $11,%eax X movb $9,%al X movl $0x3ce,%edx X outb (%dx) X movb %ah,%al X incl %edx X outb (%dx) X ret X X/* X * for Write operations, we are using PR0A as write pointer to a 32k X * window. X */ X .align 4 X .globl PVGA1ASetWrite XPVGA1ASetWrite: X decl %eax X shll $11,%eax X movb $9,%al X movl $0x3ce,%edx X outb (%dx) X movb %ah,%al X incl %edx X outb (%dx) X ret X X/* X * for Read operations, we are using PR0B as read pointer to a 32k X * window. X */ X .align 4 X .globl PVGA1ASetRead XPVGA1ASetRead: X shll $11,%eax X movb $10,%al X movl $0x3ce,%edx X outb (%dx) X movb %ah,%al X incl %edx X outb (%dx) X ret END_OF_bank.s if test 3163 -ne `wc -c