diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/aux/vga/neomagic.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/aux/vga/neomagic.c')
-rwxr-xr-x | sys/src/cmd/aux/vga/neomagic.c | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/vga/neomagic.c b/sys/src/cmd/aux/vga/neomagic.c new file mode 100755 index 000000000..32ad4dbdc --- /dev/null +++ b/sys/src/cmd/aux/vga/neomagic.c @@ -0,0 +1,351 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#include "pci.h" +#include "vga.h" + +typedef struct { + Pcidev* pci; + + int x; + int y; +} Neomagic; + +enum { + ExtCrtx = 0x19, + MaxCRT=0x85, + MaxGR=0xc7, +}; + +enum { + GeneralLockReg = 0x0A, + ExtCRTDispAddr = 0x0E, + ExtCRTOffset = 0x0F, + SysIfaceCntl1 = 0x10, + SysIfaceCntl2 = 0x11, + SingleAddrPage = 0x15, /* not changed? */ + DualAddrPage = 0x16, /* not changed? */ + PanelDispCntlReg1 = 0x20, + PanelDispCntlReg2 = 0x25, + PanelDispCntlReg3 = 0x30, + PanelVertCenterReg1 = 0x28, + PanelVertCenterReg2 = 0x29, + PanelVertCenterReg3 = 0x2A, + PanelVertCenterReg4 = 0x32, /* not 2070 */ + PanelHorizCenterReg1 = 0x33, + PanelHorizCenterReg2 = 0x34, + PanelHorizCenterReg3 = 0x35, + PanelHorizCenterReg4 = 0x36, /* 2160, 2200, 2360 */ + PanelVertCenterReg5 = 0x37, /* 2200, 2360 */ + PanelHorizCenterReg5 = 0x38, /* 2200, 2360 */ + + ExtColorModeSelect = 0x90, + + VerticalExt = 0x70, /* 2200; iobase+4 */ +}; + +static int crts[] = { + 0x1D, 0x1F, 0x21, 0x23, 0x25, 0x2F, + /* also 40-59, 60-69, 70-MaxCRT */ + -1 +}; + +/* + * Neomagic driver (fake) + */ +static void +snarf(Vga* vga, Ctlr* ctlr) +{ + int i; + Pcidev *p; + Neomagic *nm; + + generic.snarf(vga, ctlr); + + outportw(Grx, 0x2609); /* unlock neo registers */ + outportw(Grx, 0x0015); /* reset bank */ + + for(i=0; crts[i] >= 0; i++) + vga->crt[crts[i]] = vgaxi(Crtx, crts[i]); + for(i=0x40; i <= MaxCRT; i++) + vga->crt[i] = vgaxi(Crtx, i); + + for(i=0x08; i<=0x3F; i++) + vga->graphics[i] = vgaxi(Grx, i); + for(i=0x70; i<=MaxGR; i++) + vga->graphics[i] = vgaxi(Grx, i); + + if(vga->private == nil){ + vga->private = alloc(sizeof(Neomagic)); + nm = vga->private; + if((p = pcimatch(0, 0x10C8, 0)) == nil) + error("%s: not found\n", ctlr->name); + switch(p->did){ + case 0x0003: /* MagicGraph 128 ZV */ + vga->f[1] = 80000000; + vga->vmz = 2048*1024; + vga->apz = 4*1024*1024; + break; + case 0x0083: /* MagicGraph 128 ZV+ */ + vga->f[1] = 80000000; + vga->vmz = 2048*1024; + vga->apz = 4*1024*1024; + break; + case 0x0004: /* MagicGraph 128 XD */ + vga->f[1] = 90000000; + vga->vmz = 2048*1024; + vga->apz = 16*1024*1024; + break; + case 0x0005: /* MagicMedia 256 AV */ + vga->f[1] = 110000000; + vga->vmz = 2560*1024; + vga->apz = 16*1024*1024; + break; + case 0x0006: /* MagicMedia 256 ZX */ + vga->f[1] = 110000000; + vga->vmz = 4096*1024; + vga->apz = 16*1024*1024; + break; + case 0x0016: /* MagicMedia 256 XL+ */ + vga->f[1] = 110000000; + /* Vaio VESA BIOS says 6080, but then hwgc doesn't work */ + vga->vmz = 4096*1024; + vga->apz = 32*1024*1024; + break; + case 0x0001: /* MagicGraph 128 */ + case 0x0002: /* MagicGraph 128 V */ + default: + error("%s: DID %4.4uX unsupported\n", + ctlr->name, p->did); + } + nm->pci = p; + } + + ctlr->flag |= Fsnarf; +} + +static void +options(Vga*, Ctlr* ctlr) +{ + ctlr->flag |= Ulinear|Hlinear|Foptions; +} + +static void +init(Vga* vga, Ctlr* ctlr) +{ + Neomagic *nm; + int i, h, v, t; + + generic.init(vga, ctlr); + + nm = vga->private; + switch((vga->graphics[0x20]>>3)&3){ + case 0: + nm->x = 640; + nm->y = 480; + break; + case 1: + nm->x = 800; + nm->y = 600; + break; + case 2: + nm->x = 1024; + nm->y = 768; + case 3: + nm->x = 1280; + nm->y = 1024; + break; + } + + vga->crt[0x0C] = 0; /* vga starting address (offset) */ + vga->crt[0x0D] = 0; + vga->graphics[GeneralLockReg] = 0x01; /* (internal or simultaneous) */ + vga->attribute[0x10] &= ~0x40; /* 2x4 mode not right for neomagic */ + + t = 2; /* LCD only (0x01 for external) */ + switch(vga->mode->x){ + case 1280: + t |= 0x60; + break; + case 1024: + t |= 0x40; + break; + case 800: + t |= 0x20; + break; + } + if(0 && (nm->pci->did == 0x0005) || (nm->pci->did == 0x0006)){ + vga->graphics[PanelDispCntlReg1] &= 0x98; + vga->graphics[PanelDispCntlReg1] |= (t & ~0x98); + } + else{ + vga->graphics[PanelDispCntlReg1] &= 0xDC; /* save bits 7:6, 4:2 */ + vga->graphics[PanelDispCntlReg1] |= (t & ~0xDC); + } + + vga->graphics[PanelDispCntlReg2] &= 0x38; + vga->graphics[PanelDispCntlReg3] &= 0xEF; + vga->graphics[PanelVertCenterReg1] = 0x00; + vga->graphics[PanelVertCenterReg2] = 0x00; + vga->graphics[PanelVertCenterReg3] = 0x00; + vga->graphics[PanelVertCenterReg4] = 0x00; + vga->graphics[PanelVertCenterReg5] = 0x00; + vga->graphics[PanelHorizCenterReg1] = 0x00; + vga->graphics[PanelHorizCenterReg2] = 0x00; + vga->graphics[PanelHorizCenterReg3] = 0x00; + vga->graphics[PanelHorizCenterReg4] = 0x00; + vga->graphics[PanelHorizCenterReg5] = 0x00; + if(vga->mode->x < nm->x){ + vga->graphics[PanelDispCntlReg2] |= 0x01; + vga->graphics[PanelDispCntlReg3] |= 0x10; + h = ((nm->x - vga->mode->x) >> 4) - 1; + v = ((nm->y - vga->mode->y) >> 1) - 2; + switch(vga->mode->x){ + case 640: + vga->graphics[PanelHorizCenterReg1] = h; + vga->graphics[PanelVertCenterReg3] = v; + break; + case 800: + vga->graphics[PanelHorizCenterReg2] = h; + vga->graphics[PanelVertCenterReg4] = v; + break; + case 1024: + vga->graphics[PanelHorizCenterReg5] = h; + vga->graphics[PanelVertCenterReg5] = v; + break; + } + } + + vga->graphics[ExtCRTDispAddr] = 0x10; + vga->graphics[SysIfaceCntl1] &= 0x0F; + vga->graphics[SysIfaceCntl1] |= 0x30; + vga->graphics[SysIfaceCntl2] = 0x40; /* make sure MMIO is enabled */ + vga->graphics[SingleAddrPage] = 0x00; + vga->graphics[DualAddrPage] = 0x00; + vga->graphics[ExtCRTOffset] = 0x00; + t = vga->graphics[ExtColorModeSelect] & 0x70; /* colour mode extension */ + if(vga->mode->z == 8){ + t |= 0x11; + vga->crt[0x13] = vga->mode->x/8; + vga->graphics[ExtCRTOffset] = vga->mode->x>>11; + vga->graphics[0x05] = 0x00; /* linear addressing? */ + vga->crt[0x14] = 0x40; /* double word mode but don't count by 4 */ + } + else if(vga->mode->z == 16){ + t |= 0x13; + vga->crt[0x13] = vga->mode->x/4; + vga->graphics[0x05] = 0x00; /* linear addressing? */ + vga->crt[0x14] = 0x40; /* double word mode but don't count by 4 */ + vga->graphics[ExtCRTOffset] = vga->mode->x>>10; + for(i = 0; i < Pcolours; i++){ + vga->palette[i][Red] = i<<1; + vga->palette[i][Green] = i; + vga->palette[i][Blue] = i<<1; + } + } + else if(vga->mode->z == 24){ + t |= 0x14; + vga->crt[0x13] = (vga->mode->x*3)/8; +// vga->graphics[0x05] = 0x00; /* linear addressing? */ + vga->crt[0x14] = 0x40; /* double word mode but don't count by 4 */ + vga->graphics[ExtCRTOffset] = (vga->mode->x*3)>>11; + for(i = 0; i < Pcolours; i++){ + vga->palette[i][Red] = i; + vga->palette[i][Green] = i; + vga->palette[i][Blue] = i; + } + } + else + error("depth %d not supported\n", vga->mode->z); + vga->graphics[ExtColorModeSelect] = t; + + vga->misc |= 0x0C; + + ctlr->flag |= Finit; +} + +static void +load(Vga* vga, Ctlr* ctlr) +{ + vgaxo(Grx, GeneralLockReg, vga->graphics[GeneralLockReg]); + vgaxo(Grx, ExtColorModeSelect, vga->graphics[ExtColorModeSelect]); + vgaxo(Grx, PanelDispCntlReg2, vga->graphics[PanelDispCntlReg2] & 0x39); + sleep(200); + + generic.load(vga, ctlr); + + vgaxo(Grx, ExtCRTDispAddr, vga->graphics[ExtCRTDispAddr]); + vgaxo(Grx, ExtCRTOffset, vga->graphics[ExtCRTOffset] & 0x39); + vgaxo(Grx, SysIfaceCntl1, vga->graphics[SysIfaceCntl1]); + if(ctlr->flag & Ulinear) + vga->graphics[SysIfaceCntl2] |= 0x80; + vgaxo(Grx, SysIfaceCntl2, vga->graphics[SysIfaceCntl2]); + vgaxo(Grx, SingleAddrPage, vga->graphics[SingleAddrPage]); + vgaxo(Grx, DualAddrPage, vga->graphics[DualAddrPage]); + vgaxo(Grx, PanelDispCntlReg1, vga->graphics[PanelDispCntlReg1]); + vgaxo(Grx, PanelDispCntlReg2, vga->graphics[PanelDispCntlReg2]); + vgaxo(Grx, PanelDispCntlReg3, vga->graphics[PanelDispCntlReg3]); + vgaxo(Grx, PanelVertCenterReg1, vga->graphics[PanelVertCenterReg1]); + vgaxo(Grx, PanelVertCenterReg2, vga->graphics[PanelVertCenterReg2]); + vgaxo(Grx, PanelVertCenterReg3, vga->graphics[PanelVertCenterReg3]); + vgaxo(Grx, PanelVertCenterReg4, vga->graphics[PanelVertCenterReg4]); + vgaxo(Grx, PanelHorizCenterReg1, vga->graphics[PanelHorizCenterReg1]); + vgaxo(Grx, PanelHorizCenterReg2, vga->graphics[PanelHorizCenterReg2]); + vgaxo(Grx, PanelHorizCenterReg3, vga->graphics[PanelHorizCenterReg3]); + vgaxo(Grx, PanelHorizCenterReg4, vga->graphics[PanelHorizCenterReg4]); + vgaxo(Grx, PanelVertCenterReg5, vga->graphics[PanelVertCenterReg5]); + vgaxo(Grx, PanelHorizCenterReg5, vga->graphics[PanelHorizCenterReg5]); + + if(vga->mode->z != 8) + palette.load(vga, ctlr); +} + +static void +dump(Vga* vga, Ctlr* ctlr) +{ + int i; + char buf[100]; + + generic.dump(vga, ctlr); + + for(i = 0; crts[i] >= 0; i++){ + sprint(buf, "Crt%2.2uX", crts[i]); + printitem(ctlr->name, buf); + printreg(vga->crt[crts[i]]); + } + printitem(ctlr->name, "Crt40"); + for(i=0x40; i<=0x59; i++) + printreg(vga->crt[i]); + printitem(ctlr->name, "Crt60"); + for(i=0x60; i<=0x69; i++) + printreg(vga->crt[i]); + printitem(ctlr->name, "Crt70"); + for (i = 0x70; i <= MaxCRT; i++) + printreg(vga->crt[i]); + + printitem(ctlr->name, "Gr08"); + for(i=0x08; i<=0x3F; i++) + printreg(vga->graphics[i]); + printitem(ctlr->name, "Gr70"); + for(i=0x70; i<=MaxGR; i++) + printreg(vga->graphics[i]); +} + +Ctlr neomagic = { + "neomagic", /* name */ + snarf, /* snarf */ + options, /* options */ + init, /* init */ + load, /* load */ + dump, /* dump */ +}; + +Ctlr neomagichwgc = { + "neomagichwgc", /* name */ + 0, /* snarf */ + 0, /* options */ + 0, /* init */ + 0, /* load */ + 0, /* dump */ +}; |