| plan 9 kernel history: overview | file list | diff list |
1998/0511/pc/vgamach64xx.c (diff list | history)
| 1998/0511/sys/src/9/pc/vgamach64xx.c:1,288 – 1998/0803/sys/src/9/pc/vgamach64xx.c:1,292 (short | long | prev | next) | ||
|
Add more card types.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1998/0507 | #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "../port/error.h" #define Image IMAGE #include <draw.h> #include <memdraw.h> #include "screen.h" /* | |
| 1998/0508 |
| |
| 1998/0803 | * ATI Mach64(CT|ET|G*|VT|VU). | |
| 1998/0507 | */ static ushort mach64xxdid[] = { ('C'<<8)|'T', ('E'<<8)|'T', | |
| 1998/0803 | ('G'<<8)|'B', ('G'<<8)|'D', ('G'<<8)|'I', | |
| 1998/0507 | ('G'<<8)|'P', | |
| 1998/0803 | ('G'<<8)|'Q', | |
| 1998/0507 | ('G'<<8)|'T', ('G'<<8)|'U', ('V'<<8)|'T', ('V'<<8)|'U', 0, }; static Pcidev* mach64xxpci(void) { Pcidev *p; ushort *did; if((p = pcimatch(nil, 0x1002, 0)) == nil) return nil; for(did = mach64xxdid; *did; did++){ if(*did == p->did) | |
| 1998/0508 | return p; | |
| 1998/0507 | } | |
| 1998/0508 | return nil; | |
| 1998/0507 | } static void mach64xxenable(VGAscr* scr) { Pcidev *p; /* * Only once, can't be disabled for now. */ if(scr->io) return; | |
| 1998/0508 | if(p = mach64xxpci()){ /* * The CT doesn't always have the I/O base address * in the PCI base registers. There is a way to find * it via the vendor-specific PCI config space but * this will do for now. */ scr->io = p->mem[1].bar & ~0x03; if(scr->io == 0 && p->did == ('C'<<8)|'T') scr->io = 0x2EC; } | |
| 1998/0507 | } static ulong mach64xxlinear(VGAscr* scr, int* size, int* align) { ulong aperture, oaperture; int oapsize, wasupamem; Pcidev *p; oaperture = scr->aperture; oapsize = scr->apsize; wasupamem = scr->isupamem; if(wasupamem) upafree(oaperture, oapsize); scr->isupamem = 0; if(p = mach64xxpci()){ aperture = p->mem[0].bar & ~0x0F; *size = p->mem[0].size; } else aperture = 0; aperture = upamalloc(aperture, *size, *align); if(aperture == 0){ if(wasupamem && upamalloc(oaperture, oapsize, 0)) scr->isupamem = 1; } else scr->isupamem = 1; return aperture; } | |
| 1998/0511 | enum { | |
| 1998/0508 | CurClr0 = 0x0B, /* I/O Select */ CurClr1 = 0x0C, CurOffset = 0x0D, CurHVposn = 0x0E, CurHVoff = 0x0F, GenTestCntl = 0x19, | |
| 1998/0507 | }; | |
| 1998/0508 | static uchar mmoffset[] = { [CurClr0] 0x18, [CurClr1] 0x19, | |
| 1998/0511 | [CurOffset] 0x1A, [CurHVposn] 0x1B, [CurHVoff] 0x1C, | |
| 1998/0508 | [GenTestCntl] 0x34, }; | |
| 1998/0507 | static ulong ior32(VGAscr* scr, int r) { | |
| 1998/0508 | if(scr->io == 0x2EC || scr->io == 0x1C8) return inl((r<<10)+scr->io); return inl((mmoffset[r]<<2)+scr->io); | |
| 1998/0507 | } static void iow32(VGAscr* scr, int r, ulong l) { | |
| 1998/0508 | if(scr->io == 0x2EC || scr->io == 0x1C8) outl(((r)<<10)+scr->io, l); else outl((mmoffset[r]<<2)+scr->io, l); | |
| 1998/0507 | } static void mach64xxcurdisable(VGAscr* scr) { ulong r; r = ior32(scr, GenTestCntl); iow32(scr, GenTestCntl, r & ~0x80); } static void mach64xxcurload(VGAscr* scr, Cursor* curs) { uchar *p; int i, y; ulong c, s, m, r; /* * Disable the cursor. */ r = ior32(scr, GenTestCntl); iow32(scr, GenTestCntl, r & ~0x80); p = KADDR(scr->aperture); p += scr->storage; | |
| 1998/0511 | /* * Initialise the 64x64 cursor RAM array. * The cursor mode gives the following truth table: * p1 p0 colour * 0 0 Cursor Colour 0 * 0 1 Cursor Colour 1 * 1 0 Transparent * 1 1 Complement * Put the cursor into the top-right of the 64x64 array. */ | |
| 1998/0507 | for(y = 0; y < 16; y++){ for(i = 0; i < (64-16)/8; i++){ *p++ = 0xAA; *p++ = 0xAA; } c = (curs->clr[2*y]<<8)|curs->clr[y*2 + 1]; s = (curs->set[2*y]<<8)|curs->set[y*2 + 1]; m = 0x00000000; for(i = 0; i < 16; i++){ if(s & (1<<(15-i))) m |= 0x01<<(2*i); else if(c & (1<<(15-i))) ; else m |= 0x02<<(2*i); } *p++ = m; *p++ = m>>8; *p++ = m>>16; *p++ = m>>24; } memset(p, 0xAA, (64-16)*16); /* * Set the cursor hotpoint and enable the cursor. */ scr->offset = curs->offset; iow32(scr, GenTestCntl, 0x80|r); } static int mach64xxcurmove(VGAscr* scr, Point p) { int x, xo, y, yo; /* * Mustn't position the cursor offscreen even partially, * or it disappears. Therefore, if x or y is -ve, adjust the * cursor presets instead. If y is negative also have to * adjust the starting offset. */ if((x = p.x+scr->offset.x) < 0){ xo = x; x = 0; } else xo = 0; if((y = p.y+scr->offset.y) < 0){ yo = y; y = 0; } else yo = 0; iow32(scr, CurHVoff, ((64-16-yo)<<16)|(64-16-xo)); iow32(scr, CurOffset, scr->storage/8 + (-yo*2)); iow32(scr, CurHVposn, (y<<16)|x); return 0; } static void mach64xxcurenable(VGAscr* scr) { ulong r, storage; mach64xxenable(scr); if(scr->io == 0) return; r = ior32(scr, GenTestCntl); iow32(scr, GenTestCntl, r & ~0x80); iow32(scr, CurClr0, (Pwhite<<24)|(Pwhite<<16)|(Pwhite<<8)|Pwhite); iow32(scr, CurClr1, (Pblack<<24)|(Pblack<<16)|(Pblack<<8)|Pblack); /* * Find a place for the cursor data in display memory. * Must be 64-bit aligned. */ storage = (scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+7)/8; iow32(scr, CurOffset, storage); scr->storage = storage*8; /* * Cursor goes in the top right corner of the 64x64 array * so the horizontal and vertical presets are 64-16. */ iow32(scr, CurHVposn, (0<<16)|0); iow32(scr, CurHVoff, ((64-16)<<16)|(64-16)); /* * Load, locate and enable the 64x64 cursor. */ mach64xxcurload(scr, &arrow); mach64xxcurmove(scr, ZP); iow32(scr, GenTestCntl, 0x80|r); } VGAdev vgamach64xxdev = { "mach64xx", mach64xxenable, /* enable */ 0, /* disable */ 0, /* page */ mach64xxlinear, /* linear */ }; VGAcur vgamach64xxcur = { "mach64xxhwgc", mach64xxcurenable, /* enable */ mach64xxcurdisable, /* disable */ mach64xxcurload, /* load */ mach64xxcurmove, /* move */ }; | |