From 8dc1fbbb7ddae6d8701470ffad426ad7173603be Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 7 Apr 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-04-07 --- alphapc/devvga.c | 75 ++++++++++------- alphapc/fns.h | 1 + alphapc/io.h | 1 + alphapc/screen.c | 21 ++++- alphapc/screen.h | 7 ++ alphapc/vga.c | 28 +++++++ alphapc/vgas3.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++ boot/bootip.c | 3 +- port/alloc.c | 1 - port/devaudio.c | 4 +- 10 files changed, 309 insertions(+), 35 deletions(-) diff --git a/alphapc/devvga.c b/alphapc/devvga.c index 7652ce7bac913bddf66284a581e099dcdad0b47d..b7bce7211e3885c579e29e87017fd2c755156578 100644 --- a/alphapc/devvga.c +++ b/alphapc/devvga.c @@ -1,4 +1,5 @@ /* + * VGA controller */ #include "u.h" #include "../port/lib.h" @@ -69,6 +70,20 @@ vgaclose(Chan*) { } +static void +checkport(int start, int end) +{ + /* standard vga regs are OK */ + if(start >= 0x2b0 && end <= 0x2df+1) + return; + if(start >= 0x3c0 && end <= 0x3da+1) + return; + + if(iounused(start, end)) + return; + error(Eperm); +} + static long vgaread(Chan* c, void* a, long n, vlong off) { @@ -76,6 +91,7 @@ vgaread(Chan* c, void* a, long n, vlong off) char *p, *s; VGAscr *scr; ulong offset = off; + char chbuf[30]; switch(c->qid.path & ~CHDIR){ @@ -90,27 +106,32 @@ vgaread(Chan* c, void* a, long n, vlong off) free(p); nexterror(); } + + len = 0; + if(scr->dev) s = scr->dev->name; else s = "cga"; - len = snprint(p, READSTR, "type: %s\n", s); - if(scr->gscreen) - len += snprint(p+len, READSTR-len, "size: %dx%dx%d\n", + len += snprint(p+len, READSTR-len, "type %s\n", s); + + if(scr->gscreen) { + len += snprint(p+len, READSTR-len, "size %dx%dx%d %s\n", scr->gscreen->r.max.x, scr->gscreen->r.max.y, - scr->gscreen->depth); - if(scr->cur) - s = scr->cur->name; - else - s = "off"; - len += snprint(p+len, READSTR-len, "hwgc: %s\n", s); + scr->gscreen->depth, chantostr(chbuf, scr->gscreen->chan)); + + if(Dx(scr->gscreen->r) != Dx(physgscreenr) + || Dy(scr->gscreen->r) != Dy(physgscreenr)) + len += snprint(p+len, READSTR-len, "actualsize %dx%d\n", + physgscreenr.max.x, physgscreenr.max.y); + } + + len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off"); + len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off"); if(scr->pciaddr) - snprint(p+len, READSTR-len, "addr: 0x%lux\n", - scr->pciaddr); + snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->pciaddr); else - snprint(p+len, READSTR-len, "addr: 0x%lux\n", - scr->aperture); - + snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->aperture); n = readstr(offset, a, n, p); poperror(); free(p); @@ -159,10 +180,6 @@ vgactl(char* a) if(n < 2) error(Ebadarg); - /* BUG: drawinit should become a different message rather than piggybacking */ - if(scr && scr->dev && scr->dev->drawinit) - scr->dev->drawinit(scr); - if(strcmp(field[1], "off") == 0){ lock(&cursor); if(scr->cur){ @@ -277,17 +294,8 @@ vgactl(char* a) return; } else if(strcmp(field[0], "drawinit") == 0){ - /* - * This is a separate message, but first we need to make - * aux/vga send it; once everyone has the new vga, we - * can take the drawinit stuff out of hwgc. - */ - - /* if(scr && scr->dev && scr->dev->drawinit) scr->dev->drawinit(scr); - */ - return; } else if(strcmp(field[0], "linear") == 0){ @@ -311,9 +319,9 @@ vgactl(char* a) } */ else if(strcmp(field[0], "blank") == 0){ - if(n < 2) + if(n < 1) error(Ebadarg); - drawblankscreen(atoi(field[1])); + drawblankscreen(1); return; } else if(strcmp(field[0], "hwaccel") == 0){ @@ -325,6 +333,15 @@ vgactl(char* a) hwaccel = 0; return; } + else if(strcmp(field[0], "hwblank") == 0){ + if(n < 2) + error(Ebadarg); + if(strcmp(field[1], "on") == 0) + hwblank = 1; + else if(strcmp(field[1], "off") == 0) + hwblank = 0; + return; + } error(Ebadarg); } diff --git a/alphapc/fns.h b/alphapc/fns.h index adf4e7e3f74ffb719898482af88abafb1f08abc9..24392836d183a4c851065f409367aa2735766b3d 100644 --- a/alphapc/fns.h +++ b/alphapc/fns.h @@ -44,6 +44,7 @@ void intrenable(int, void (*)(Ureg*, void*), void*, int, char*); int ioalloc(int, int, int, char*); void iofree(int); void ioinit(void); +int iounused(int, int); int iprint(char*, ...); int irqallocread(char*, long, vlong); int isaconfig(char*, int, ISAConf*); diff --git a/alphapc/io.h b/alphapc/io.h index 49a97ccd3e235a746296afdaf68adcc1fc131b05..59913fbe8148e2576a29f5fbe89cbfb6a6d61a10 100644 --- a/alphapc/io.h +++ b/alphapc/io.h @@ -16,6 +16,7 @@ enum { IrqAUX = 12, /* PS/2 port */ IrqIRQ13 = 13, /* coprocessor on 386 */ IrqATA0 = 14, + IrqATA1 = 15, MaxIrqPIC = 15, VectorPIC = 64, diff --git a/alphapc/screen.c b/alphapc/screen.c index 1906ef16bbf3b8e2dee870617e61534b171922ea..673b6a2326e54fd346b02538b70c08019a0e5e70 100644 --- a/alphapc/screen.c +++ b/alphapc/screen.c @@ -51,7 +51,7 @@ screensize(int x, int y, int z, ulong chan) * be given back if aperture is set. */ if(scr->aperture == 0){ - int width = (x*(1<data->bdata, 0x15, (x*y*z+7)/8); /* RSC BUG */ + memfillcolor(gscreen, DRed); + scr->palettedepth = 6; /* default */ scr->gscreendata = &gscreendata; scr->memdefont = getmemdefont(); scr->gscreen = gscreen; + physgscreenr = gscreen->r; + drawcmap(); return 0; } @@ -101,8 +106,7 @@ screenaperture(int size, int align) aperture = scr->dev->linear(scr, &size, &align); if(aperture == 0) return 1; - } - else{ + }else{ aperture = upamalloc(0, size, align); if(aperture == 0) return 1; @@ -460,6 +464,7 @@ Memimage *lastbadi; Memdata *lastbad; Memimage *lastbadsrc, *lastbaddst; int hwaccel = 1; +int hwblank = 1; int hwdraw(Memdrawparam *par) @@ -513,3 +518,13 @@ hwdraw(Memdrawparam *par) return 0; } + +void +blankscreen(int blank) +{ + VGAscr *scr; + + scr = &vgascreen[0]; + if(hwblank && scr->blank) + scr->blank(scr, blank); +} diff --git a/alphapc/screen.h b/alphapc/screen.h index 565159b1332ff5163fd2d3f6093e7a9b9d5efa95..a68f98a616caeb6d7c28616a7253847cd279f6a1 100644 --- a/alphapc/screen.h +++ b/alphapc/screen.h @@ -104,14 +104,17 @@ struct VGAscr { ulong colormap[Pcolours][3]; int palettedepth; + ulong *mmio; Memimage* gscreen; Memdata* gscreendata; Memsubfont* memdefont; int (*fill)(VGAscr*, Rectangle, ulong); int (*scroll)(VGAscr*, Rectangle, Rectangle); + void (*blank)(VGAscr*, int); ulong id; /* internal identifier for driver use */ }; + extern VGAscr vgascreen[]; enum { @@ -123,6 +126,7 @@ extern void mousectl(char*[], int); /* screen.c */ extern int hwaccel; /* use hw acceleration; default on */ +extern int hwblank; /* use hw blanking; default on */ extern void flushmemscreen(Rectangle); extern int cursoron(int); extern void cursoroff(int); @@ -130,6 +134,7 @@ extern void setcursor(Cursor*); extern int screensize(int, int, int, ulong); extern int screenaperture(int, int); extern Rectangle physgscreenr; /* actual monitor size */ +extern void blankscreen(int); /* devdraw.c */ extern void deletescreenimage(void); @@ -138,5 +143,7 @@ extern int drawhasclients(void); /* vga.c */ extern void vgascreenwin(VGAscr*); extern void vgaimageinit(ulong); +extern ulong vgapcilinear(VGAscr*, int*, int*, int, int); extern void drawblankscreen(int); +extern void vgablank(VGAscr*, int); diff --git a/alphapc/vga.c b/alphapc/vga.c index 043143b55c7e804d9f130502be0e1abd4d0421a9..2e32518c1c771cd2d531534d974038bdfd859a39 100644 --- a/alphapc/vga.c +++ b/alphapc/vga.c @@ -189,3 +189,31 @@ vgascreenwin(VGAscr* scr) screenputs = vgascreenputs; } + +/* + * Supposedly this is the way to turn DPMS + * monitors off using just the VGA registers. + * Unfortunately, it seems to mess up the video mode + * on the cards I've tried. + */ +void +vgablank(VGAscr*, int blank) +{ + uchar seq1, crtc17; + + if(blank) { + seq1 = 0x00; + crtc17 = 0x80; + } else { + seq1 = 0x20; + crtc17 = 0x00; + } + + outs(Seqx, 0x0100); /* synchronous reset */ + seq1 |= vgaxi(Seqx, 1) & ~0x20; + vgaxo(Seqx, 1, seq1); + crtc17 |= vgaxi(Crtx, 0x17) & ~0x80; + delay(10); + vgaxo(Crtx, 0x17, crtc17); + outs(Crtx, 0x0300); /* end synchronous reset */ +} diff --git a/alphapc/vgas3.c b/alphapc/vgas3.c index 37e84849c1346717a4f55b1903e138a8927c211c..20165c5355093a8e3d43ec84d6bb9777f8de1167 100644 --- a/alphapc/vgas3.c +++ b/alphapc/vgas3.c @@ -284,6 +284,208 @@ s3move(VGAscr* scr, Point p) return 0; } +/* + * The manual gives byte offsets, but we want ulong offsets, hence /4. + */ +enum { + SrcBase = 0xA4D4/4, + DstBase = 0xA4D8/4, + Stride = 0xA4E4/4, + FgrdData = 0xA4F4/4, + WidthHeight = 0xA504/4, + SrcXY = 0xA508/4, + DestXY = 0xA50C/4, + Command = 0xA500/4, + SubStat = 0x8504/4, + FifoStat = 0x850C/4, +}; + +/* + * Wait for writes to VGA memory via linear aperture to flush. + */ +enum {Maxloop = 1<<24}; +struct { + ulong linear; + ulong fifo; + ulong idle; +} waitcount; + +static void +waitforlinearfifo(VGAscr *scr) +{ + ulong *mmio; + long x; + static ulong nwaitforlinearfifo; + ulong mask, val; + + switch(scr->id){ + default: + panic("unknown scr->id in s3 waitforlinearfifo"); + case 0xE131: /* ViRGE */ + case 0xE13D: /* ViRGE/VX */ + mask = 0x0F<<6; + val = 0x08<<6; + break; + case 0xE110: /* ViRGE/GX2 */ + mask = 0x1F<<6; + val = 0x10<<6; + break; + } + mmio = scr->mmio; + x = 0; + while((mmio[FifoStat]&mask) != val && x++ < Maxloop) + waitcount.linear++; +} + +static void +waitforfifo(VGAscr *scr, int entries) +{ + ulong *mmio; + long x; + static ulong nwaitforfifo; + + mmio = scr->mmio; + x = 0; + while((mmio[SubStat]&0x1F00) < ((entries+2)<<8) && x++ < Maxloop) + waitcount.fifo++; +} + +static void +waitforidle(VGAscr *scr) +{ + ulong *mmio; + long x; + + mmio = scr->mmio; + x = 0; + while((mmio[SubStat]&0x3F00) != 0x3000 && x++ < Maxloop) + waitcount.idle++; +} + +static int +hwscroll(VGAscr *scr, Rectangle r, Rectangle sr) +{ + enum { Bitbltop = 0xCC }; /* copy source */ + ulong *mmio; + ulong cmd, stride; + Point dp, sp; + int did, d; + + d = scr->gscreen->depth; + did = (d-8)/8; + cmd = 0x00000020|(Bitbltop<<17)|(did<<2); + stride = Dx(scr->gscreen->r)*d/8; + + if(r.min.x <= sr.min.x){ + cmd |= 1<<25; + dp.x = r.min.x; + sp.x = sr.min.x; + }else{ + dp.x = r.max.x-1; + sp.x = sr.max.x-1; + } + + if(r.min.y <= sr.min.y){ + cmd |= 1<<26; + dp.y = r.min.y; + sp.y = sr.min.y; + }else{ + dp.y = r.max.y-1; + sp.y = sr.max.y-1; + } + + mmio = scr->mmio; + waitforlinearfifo(scr); + waitforfifo(scr, 7); + mmio[SrcBase] = scr->aperture; + mmio[DstBase] = scr->aperture; + mmio[Stride] = (stride<<16)|stride; + mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r); + mmio[SrcXY] = (sp.x<<16)|sp.y; + mmio[DestXY] = (dp.x<<16)|dp.y; + mmio[Command] = cmd; + waitforidle(scr); + return 1; +} + +static int +hwfill(VGAscr *scr, Rectangle r, ulong sval) +{ + enum { Bitbltop = 0xCC }; /* copy source */ + ulong *mmio; + ulong cmd, stride; + int did, d; + + d = scr->gscreen->depth; + did = (d-8)/8; + cmd = 0x16000120|(Bitbltop<<17)|(did<<2); + stride = Dx(scr->gscreen->r)*d/8; + mmio = scr->mmio; + waitforlinearfifo(scr); + waitforfifo(scr, 8); + mmio[SrcBase] = scr->aperture; + mmio[DstBase] = scr->aperture; + mmio[DstBase] = scr->aperture; + mmio[Stride] = (stride<<16)|stride; + mmio[FgrdData] = sval; + mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r); + mmio[DestXY] = (r.min.x<<16)|r.min.y; + mmio[Command] = cmd; + waitforidle(scr); + return 1; +} + +enum { + CursorSyncCtl = 0x0D, /* in Seqx */ + VsyncHi = 0x80, + VsyncLo = 0x40, + HsyncHi = 0x20, + HsyncLo = 0x10, +}; + +static void +s3blank(int blank) +{ + uchar x; + + x = vgaxi(Seqx, CursorSyncCtl); + x &= ~0xF0; + if(blank) + x |= VsyncLo | HsyncLo; + vgaxo(Seqx, CursorSyncCtl, x); +} + +static void +s3drawinit(VGAscr *scr) +{ + ulong id; + + id = (vgaxi(Crtx, 0x30)<<8)|vgaxi(Crtx, 0x2E); + scr->id = id; + + /* + * It's highly likely that other ViRGEs will work without + * change to the driver, with the exception of the size of + * the linear aperture memory write FIFO. Since we don't + * know that size, I'm not turning them on. See waitforlinearfifo + * above. + */ + switch(id){ + case 0xE131: /* ViRGE */ + case 0xE13D: /* ViRGE/VX */ + case 0xE110: /* ViRGE/GX2 */ + scr->mmio = (ulong*)(scr->pciaddr+0x1000000); +/* + * Untested on the Alpha. + */ +/* + scr->fill = hwfill; + scr->scroll = hwscroll; +*/ + /* scr->blank = hwblank; */ + } +} + VGAdev vgas3dev = { "s3", @@ -291,6 +493,7 @@ VGAdev vgas3dev = { 0, s3page, s3linear, + s3drawinit, }; VGAcur vgas3cur = { diff --git a/boot/bootip.c b/boot/bootip.c index f63368ebf30d4998c4dc2967e242ab4cffbfa21b..74d9e382183ccd385ff01dd1d32298a3792501fe 100644 --- a/boot/bootip.c +++ b/boot/bootip.c @@ -42,7 +42,8 @@ configip(void) case 'b': case 'h': case 'm': - ARGF(); + p = ARGF(); + USED(p); break; } ARGEND; diff --git a/port/alloc.c b/port/alloc.c index fd35e828895e19e79a1c95755f428e05ca390176..c712bd557c6a8f7e306bbe2fa6529d1822a7555f 100644 --- a/port/alloc.c +++ b/port/alloc.c @@ -76,7 +76,6 @@ static void ppanic(Pool *p, char *fmt, ...) { va_list v; - int n; Private *pv; char msg[sizeof pv->msg]; diff --git a/port/devaudio.c b/port/devaudio.c index 28560b268de86699549217dd06ed295c566f4384..e07caab466780b06ebc62c7a0920802a14688333 100644 --- a/port/devaudio.c +++ b/port/devaudio.c @@ -1188,8 +1188,10 @@ swab(uchar *a) { ulong *p, *ep, b; - if(!SBswab) + if(!SBswab){ + USED(a); return; + } p = (ulong*)a; ep = p + (Bufsize>>2); while(p < ep) {