From 19bf0531d825cfca85fbf68cbce60f2a3e7cf7e3 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 3 Jun 1997 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1997-06-03 --- carrera/main.c | 2 + pc/main.c | 2 + pc/vgatvp3026.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++++ port/devdup.c | 2 +- port/pgrp.c | 7 ++ port/portdat.h | 8 +- port/sysfile.c | 30 +++++-- 7 files changed, 269 insertions(+), 8 deletions(-) create mode 100644 pc/vgatvp3026.c diff --git a/carrera/main.c b/carrera/main.c index 9a4f29ce43d54ac8ea755df94f9c8e91cfbf98d4..54fa4803f9e2a742a218d719e7cd4ec8e46ce59a 100644 --- a/carrera/main.c +++ b/carrera/main.c @@ -359,6 +359,8 @@ userinit(void) p->egrp->ref = 1; p->fgrp = smalloc(sizeof(Fgrp)); p->fgrp->ref = 1; + p->fgrp->fd = smalloc(DELTAFD*sizeof(Chan*)); + p->fgrp->nfd = DELTAFD; p->rgrp = newrgrp(); p->procmode = 0640; diff --git a/pc/main.c b/pc/main.c index 30b22e739a63257e3dbd1953234b7c2605b73000..6835f92c0766d5cc8a037cb981bb5699b09d9bda 100644 --- a/pc/main.c +++ b/pc/main.c @@ -234,6 +234,8 @@ userinit(void) p->egrp->ref = 1; p->fgrp = smalloc(sizeof(Fgrp)); p->fgrp->ref = 1; + p->fgrp->fd = smalloc(DELTAFD*sizeof(Chan*)); + p->fgrp->nfd = DELTAFD; p->rgrp = newrgrp(); p->procmode = 0640; diff --git a/pc/vgatvp3026.c b/pc/vgatvp3026.c new file mode 100644 index 0000000000000000000000000000000000000000..ba274a22374eb7981196c8cdf06df9264dbba446 --- /dev/null +++ b/pc/vgatvp3026.c @@ -0,0 +1,226 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" + +#include +#include "screen.h" +#include "vga.h" + +extern Cursor curcursor; + +/* + * TVP3026 Viewpoint Video Interface Pallette. + * Assumes hooked up to an S3 Vision968. + */ +enum { + Index = 0x00, /* Index */ + Data = 0x0A, /* Data */ + + CaddrW = 0x04, /* Colour Write Address */ + Cdata = 0x05, /* Colour Data */ + + Cctl = 0x09, /* Direct Cursor Control */ + Cram = 0x0B, /* Cursor Ram Data */ + Cxlsb = 0x0C, /* Cursor X LSB */ + Cxmsb = 0x0D, /* Cursor X MSB */ + Cylsb = 0x0E, /* Cursor Y LSB */ + Cymsb = 0x0F, /* Cursor Y MSB */ + + Icctl = 0x06, /* Indirect Cursor Control */ +}; + +/* + * Lower 2-bits of indirect DAC register + * addressing. + */ +static ushort dacxreg[4] = { + PaddrW, Pdata, Pixmask, PaddrR +}; + +static Point hotpoint; + +static uchar +tvp3026io(uchar reg, uchar data) +{ + uchar crt55; + + crt55 = vgaxi(Crtx, 0x55) & 0xFC; + vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03)); + vgao(dacxreg[reg & 0x03], data); + + return crt55; +} + +static void +tvp3026o(uchar reg, uchar data) +{ + uchar crt55; + + crt55 = tvp3026io(reg, data); + vgaxo(Crtx, 0x55, crt55); +} + +void +tvp3026xo(uchar index, uchar data) +{ + uchar crt55; + + crt55 = tvp3026io(Index, index); + vgaxo(Crtx, 0x55, crt55|((Data>>2) & 0x03)); + vgao(dacxreg[Data & 0x03], data); + vgaxo(Crtx, 0x55, crt55); +} + +static void +load(Cursor *c) +{ + int x, y; + + /* + * Lock the DAC registers so we can update the + * cursor bitmap if necessary. + * If it's the same as the last cursor we loaded, + * just make sure it's enabled. + */ + lock(&palettelock); + if(memcmp(c, &curcursor, sizeof(Cursor)) == 0){ + tvp3026o(Cctl, 0x01); + unlock(&palettelock); + return; + } + memmove(&curcursor, c, sizeof(Cursor)); + + /* + * Make sure cursor is off by initialising the cursor + * control to defaults. + * Write to the indirect control register to make sure + * direct register is enabled and upper 2 bits of cursor + * RAM address are 0. + * The LSBs of the cursor RAM address are in PaddrW. + */ + tvp3026xo(Icctl, 0x90); + tvp3026o(Cctl, 0x00); + vgao(PaddrW, 0x00); + + /* + * Initialise the 64x64 cursor RAM array. There are 2 planes, + * p0 and p1. Data is written 8 pixels per byte, with p0 in the + * first 512 bytes of the array and p1 in the second. + * The cursor is set in 3-colour mode which gives the following + * truth table: + * p1 p0 colour + * 0 0 transparent + * 0 1 cursor colour 0 + * 1 0 cursor colour 1 + * 1 1 cursor colour 2 + * Put the cursor into the top-left of the 64x64 array. + * The 0,0 cursor point is bottom-right, so positioning will + * have to take that into account. + */ + for(y = 0; y < 64; y++){ + for(x = 0; x < 64/8; x++){ + if(x < 16/8 && y < 16) + tvp3026o(Cram, c->clr[x+y*2]); + else + tvp3026o(Cram, 0x00); + } + } + for(y = 0; y < 64; y++){ + for(x = 0; x < 64/8; x++){ + if(x < 16/8 && y < 16) + tvp3026o(Cram, c->set[x+y*2]); + else + tvp3026o(Cram, 0x00); + } + } + + /* + * Initialise the cursor hot-point + * and enable the cursor in 3-colour mode. + */ + hotpoint.x = 64+c->offset.x; + hotpoint.y = 64+c->offset.y; + + tvp3026o(Cctl, 0x01); + + unlock(&palettelock); +} + +static void +enable(void) +{ + lock(&palettelock); + + /* + * Make sure cursor is off and direct control enabled. + */ + tvp3026xo(Icctl, 0x90); + tvp3026o(Cctl, 0x00); + + /* + * Overscan colour, + * cursor colour 1 (white), + * cursor colour 2, 3 (black). + */ + tvp3026o(CaddrW, 0x00); + tvp3026o(Cdata, Pwhite); tvp3026o(Cdata, Pwhite); tvp3026o(Cdata, Pwhite); + tvp3026o(Cdata, Pwhite); tvp3026o(Cdata, Pwhite); tvp3026o(Cdata, Pwhite); + tvp3026o(Cdata, Pblack); tvp3026o(Cdata, Pblack); tvp3026o(Cdata, Pblack); + tvp3026o(Cdata, Pblack); tvp3026o(Cdata, Pblack); tvp3026o(Cdata, Pblack); + + /* + * Enable the cursor in 3-colour mode. + */ + tvp3026o(Cctl, 0x01); + + unlock(&palettelock); +} + +static int +move(Point p) +{ + int x, y; + + if(canlock(&palettelock) == 0) + return 1; + + x = p.x+hotpoint.x; + y = p.y+hotpoint.y; + + tvp3026o(Cxlsb, x & 0xFF); + tvp3026o(Cxmsb, (x>>8) & 0x0F); + tvp3026o(Cylsb, y & 0xFF); + tvp3026o(Cymsb, (y>>8) & 0x0F); + + unlock(&palettelock); + + return 0; +} + +static void +disable(void) +{ + lock(&palettelock); + tvp3026xo(Icctl, 0x90); + tvp3026o(Cctl, 0x00); + unlock(&palettelock); +} + +Hwgc tvp3026hwgc = { + "tvp3026hwgc", + enable, + load, + move, + disable, + + 0, +}; + +void +vgatvp3026link(void) +{ + addhwgclink(&tvp3026hwgc); +} diff --git a/port/devdup.c b/port/devdup.c index 7c8db30e0fdaede8a6bc865538b02843f7decab0..1ba68778cae7fe87f32182a7c435944f94a73f4e 100644 --- a/port/devdup.c +++ b/port/devdup.c @@ -13,7 +13,7 @@ dupgen(Chan *c, Dirtab*, int, int s, Dir *dp) Chan *f; static int perm[] = { 0400, 0200, 0600, 0 }; - if(s >= NFD) + if(s >= fgrp->maxfd) return -1; if((f=fgrp->fd[s]) == 0) return 0; diff --git a/port/pgrp.c b/port/pgrp.c index ac4f3c0b041bfef080a3bc21d8058c119b333042..e2b6ae63b47be620aa5a6ca62beadf8daaed08b7 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -167,6 +167,12 @@ dupfgrp(Fgrp *f) int i; new = smalloc(sizeof(Fgrp)); + /* Make new fd list shorter if possible, preserving quantization */ + new->nfd = f->maxfd+1; + i = new->nfd%DELTAFD; + if(i != 0) + new->nfd += DELTAFD - i; + new->fd = smalloc(new->nfd*sizeof(Chan*)); new->ref = 1; lock(f); @@ -198,6 +204,7 @@ closefgrp(Fgrp *f) if(c = f->fd[i]) cclose(c); + free(f->fd); free(f); } diff --git a/port/portdat.h b/port/portdat.h index e4bdb3e6b2d957d08486ed6b47ddfa0ab6c1d450..bd0bf933c78b346ef26a5c08d21b6a946baf5ccb 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -430,10 +430,16 @@ struct Evalue struct Fgrp { Ref; - Chan *fd[NFD]; + Chan **fd; + int nfd; /* number allocated */ int maxfd; /* highest fd in use */ }; +enum +{ + DELTAFD = 20 /* incremental increase in Fgrp.fd's */ +}; + struct Palloc { Lock; diff --git a/port/sysfile.c b/port/sysfile.c index 54b39416302e32890ec8391be472a96be9e9f672..74cb2de3c055e4ccb3078c279419838ab722df69 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -14,9 +14,10 @@ newfd(Chan *c) { int i; Fgrp *f = up->fgrp; + Chan **newfd, **oldfd; lock(f); - for(i=0; infd; i++) if(f->fd[i] == 0){ if(i > f->maxfd) f->maxfd = i; @@ -24,10 +25,27 @@ newfd(Chan *c) unlock(f); return i; } + /* + * Unbounded allocation is unwise; besides, there are only 16 bits + * of fid in 9P + */ + if(f->nfd >= 5000){ + unlock(f); + exhausted("file descriptors"); + return -1; + } + newfd = smalloc((f->nfd+DELTAFD)*sizeof(Chan*)); + oldfd = f->fd; + memmove(newfd, oldfd, f->nfd*sizeof(Chan*)); + f->fd = newfd; + f->nfd += DELTAFD; + f->maxfd = i; + f->fd[i] = c; unlock(f); -print("process %d (%s) out of file descriptors\n", up->pid, up->text); - exhausted("file descriptors"); - return 0; + free(oldfd); + if(i%100 == 0) + pprint("warning: process exceeds %d file descriptors\n", i); + return i; } Chan* @@ -40,7 +58,7 @@ fdtochan(int fd, int mode, int chkmnt, int iref) f = up->fgrp; lock(f); - if(fd<0 || NFD<=fd || (c = f->fd[fd])==0) { + if(fd<0 || f->nfd<=fd || (c = f->fd[fd])==0) { unlock(f); error(Ebadfd); } @@ -156,7 +174,7 @@ sysdup(ulong *arg) c = fdtochan(arg[0], -1, 0, 1); fd = arg[1]; if(fd != -1){ - if(fd<0 || NFD<=fd) { + if(fd<0 || f->nfd<=fd) { cclose(c); error(Ebadfd); }