| plan 9 kernel history: overview | file list | diff list |
1997/1101/pc/vgas3.c (diff list | history)
| pc/vgas3.c on 1994/0803 | ||
| 1994/0803 | #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" | |
| 1997/1101 | #include "io.h" | |
| 1994/0803 | #include "../port/error.h" | |
| 1997/1101 | #define Image IMAGE #include <draw.h> #include <memdraw.h> | |
| 1994/0803 | #include "screen.h" | |
| 1997/1101 | static int s3pageset(VGAscr* scr, int page) | |
| 1994/0803 | { | |
| 1997/1101 | uchar crt35, crt51; int opage; | |
| 1994/0803 | ||
| 1997/1101 | crt35 = vgaxi(Crtx, 0x35); if(scr->gscreen->ldepth == 3){ | |
| 1994/0803 | /* * The S3 registers need to be unlocked for this. * Let's hope they are already: * vgaxo(Crtx, 0x38, 0x48); * vgaxo(Crtx, 0x39, 0xA0); * * The page is 6 bits, the lower 4 bits in Crt35<3:0>, * the upper 2 in Crt51<3:2>. */ vgaxo(Crtx, 0x35, page & 0x0F); | |
| 1997/1101 | crt51 = vgaxi(Crtx, 0x51); vgaxo(Crtx, 0x51, (crt51 & ~0x0C)|((page & 0x30)>>2)); opage = ((crt51 & 0x0C)<<2)|(crt35 & 0x0F); | |
| 1994/0803 | } | |
| 1997/1101 | else{ | |
| 1994/0803 | vgaxo(Crtx, 0x35, (page<<2) & 0x0C); | |
| 1997/1101 | opage = (crt35>>2) & 0x03; } return opage; | |
| 1994/0803 | } static void | |
| 1997/1101 | s3page(VGAscr* scr, int page) | |
| 1994/0803 | { | |
| 1997/1101 | lock(&scr->devlock); s3pageset(scr, page); unlock(&scr->devlock); } static ulong s3linear(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 = pcimatch(nil, 0x5333, 0)){ 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; } static void s3vsyncactive(void) { | |
| 1994/0803 | /* * Hardware cursor information is fetched from display memory * during the horizontal blank active time. The 80x chips may hang * if the cursor is turned on or off during this period. */ while((vgai(Status1) & 0x08) == 0) ; } static void | |
| 1997/1101 | s3disable(VGAscr*) | |
| 1994/0803 | { uchar crt45; /* * Turn cursor off. */ crt45 = vgaxi(Crtx, 0x45) & 0xFE; | |
| 1997/1101 | s3vsyncactive(); | |
| 1994/0803 | vgaxo(Crtx, 0x45, crt45); } static void | |
| 1997/1101 | s3enable(VGAscr* scr) | |
| 1997/0327 | { | |
| 1994/0803 | int i; | |
| 1997/1101 | ulong storage; | |
| 1994/0803 | ||
| 1997/1101 | s3disable(scr); | |
| 1994/0803 | /* * Cursor colours. Set both the CR0[EF] and the colour * stack in case we are using a 16-bit RAMDAC. | |
| 1994/0804 | * Why are these colours reversed? | |
| 1994/0803 | */ | |
| 1995/0126 | vgaxo(Crtx, 0x0E, Pwhite); vgaxo(Crtx, 0x0F, Pblack); | |
| 1994/0803 | vgaxi(Crtx, 0x45); for(i = 0; i < 4; i++) | |
| 1995/0126 | vgaxo(Crtx, 0x4A, Pwhite); | |
| 1994/0803 | vgaxi(Crtx, 0x45); for(i = 0; i < 4; i++) | |
| 1995/0126 | vgaxo(Crtx, 0x4B, Pblack); | |
| 1994/0803 | /* * Find a place for the cursor data in display memory. * Must be on a 1024-byte boundary. */ | |
| 1997/1101 | storage = (scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024; | |
| 1994/0803 | vgaxo(Crtx, 0x4C, (storage>>8) & 0x0F); vgaxo(Crtx, 0x4D, storage & 0xFF); storage *= 1024; | |
| 1997/1101 | scr->storage = storage; | |
| 1994/0803 | /* * Enable the cursor in X11 mode. */ vgaxo(Crtx, 0x55, vgaxi(Crtx, 0x55)|0x10); | |
| 1997/1101 | s3vsyncactive(); | |
| 1994/0803 | vgaxo(Crtx, 0x45, 0x01); } static void | |
| 1997/1101 | s3load(VGAscr* scr, Cursor* curs) | |
| 1994/0803 | { | |
| 1994/0804 | uchar *p; | |
| 1997/1101 | int opage, x, y; | |
| 1994/0803 | /* | |
| 1997/1101 | * Disable the cursor and * set the pointer to the two planes. * Is linear addressing turned on? This will determine * how we access the cursor storage. | |
| 1994/0809 | */ | |
| 1997/1101 | s3disable(scr); | |
| 1994/0809 | ||
| 1997/1101 | p = KADDR(scr->aperture); lock(&scr->devlock); opage = s3pageset(scr, scr->storage>>16); p += (scr->storage & 0xFFFF); | |
| 1994/0803 | /* * The cursor is set in X11 mode which gives the following * truth table: * and xor colour * 0 0 underlying pixel colour * 0 1 underlying pixel colour * 1 0 background colour * 1 1 foreground colour * Put the cursor into the top-left of the 64x64 array. | |
| 1994/0809 | * * The cursor pattern in memory is interleaved words of * AND and XOR patterns. | |
| 1994/0803 | */ for(y = 0; y < 64; y++){ | |
| 1994/0804 | for(x = 0; x < 64/8; x += 2){ if(x < 16/8 && y < 16){ | |
| 1997/1101 | *p++ = curs->clr[2*y + x]|curs->set[2*y + x]; *p++ = curs->clr[2*y + x+1]|curs->set[2*y + x+1]; *p++ = curs->set[2*y + x]; *p++ = curs->set[2*y + x+1]; | |
| 1994/0803 | } else { | |
| 1994/0804 | *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; | |
| 1994/0803 | } } } | |
| 1997/1101 | s3pageset(scr, opage); unlock(&scr->devlock); | |
| 1994/0803 | /* | |
| 1997/1101 | * Save the cursor hotpoint and enable the cursor. | |
| 1994/0803 | */ | |
| 1997/1101 | scr->offset = curs->offset; s3vsyncactive(); | |
| 1994/0803 | vgaxo(Crtx, 0x45, 0x01); } static int | |
| 1997/1101 | s3move(VGAscr* scr, Point p) | |
| 1994/0803 | { | |
| 1994/0804 | 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 offset instead. | |
| 1994/0809 | * There seems to be a bug in that if the offset is 1, the * cursor doesn't disappear off the left edge properly, so * round it up to be even. | |
| 1994/0804 | */ | |
| 1997/1101 | if((x = p.x+scr->offset.x) < 0){ | |
| 1994/0804 | xo = -x; xo = ((xo+1)/2)*2; x = 0; } else xo = 0; | |
| 1997/1101 | if((y = p.y+scr->offset.y) < 0){ | |
| 1994/0804 | yo = -y; y = 0; } else yo = 0; vgaxo(Crtx, 0x46, (x>>8) & 0x07); vgaxo(Crtx, 0x47, x & 0xFF); vgaxo(Crtx, 0x49, y & 0xFF); vgaxo(Crtx, 0x4E, xo); vgaxo(Crtx, 0x4F, yo); vgaxo(Crtx, 0x48, (y>>8) & 0x07); | |
| 1994/0803 | return 0; } | |
| 1997/1101 | VGAdev vgas3dev = { "s3", | |
| 1995/0126 | 0, | |
| 1997/1101 | 0, s3page, s3linear, | |
| 1994/0803 | }; | |
| 1997/1101 | VGAcur vgas3cur = { "s3hwgc", | |
| 1995/0126 | ||
| 1997/1101 | s3enable, s3disable, s3load, s3move, | |
| 1995/0126 | }; | |