From e0e70efe06e5592cc90eb2ba7dc4c51e0bf6680d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 18 Aug 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-08-18 --- gnot/devlbp.c | 803 ++++++++++++++++++++++++++++++++++++++++++++++++++ port/devbit.c | 14 + ss/main.c | 4 +- 3 files changed, 819 insertions(+), 2 deletions(-) create mode 100644 gnot/devlbp.c diff --git a/gnot/devlbp.c b/gnot/devlbp.c new file mode 100644 index 0000000000000000000000000000000000000000..2488fe1b7a7a02cfd03b471fe414bbcbf1c77c18 --- /dev/null +++ b/gnot/devlbp.c @@ -0,0 +1,803 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/error.h" + +#include +#include + +#include "devtab.h" + +#define GSHORT(p) (((p)[0]<<0) | ((p)[1]<<8)) +#define GLONG(p) ((GSHORT(p)<<0) | (GSHORT(p+2)<<16)) +#define PSHORT(p, v) ((p)[0]=(v), (p)[1]=((v)>>8)) +#define PLONG(p, v) (PSHORT(p, (v)), PSHORT(p+2, (v)>>16)) + +#define ISKVA(va) ((ulong)(va)&KZERO) + +typedef struct Lbpfifo { + unsigned long fifo; + unsigned short csr; + unsigned short hblank; +} Lbpfifo; + +enum Csrin { + BINT = 0x0001, VEND = 0x0002, EFL = 0x0004, HFL = 0x0008, + FFL = 0x0010, VSTARTL = 0x0020, + PPRDYL = 0x0100, RDY = 0x0200, SBSY = 0x0400, SCIN = 0x0800, + SCLKIN = 0x1000, VSREQ = 0x2000, +}; + +enum Csrout { + GO = 0x0001, EOL = 0x0002, EFINTEN = 0x0004, HFINTEN = 0x0008, + VCLRL = 0x0010, FOURHDPI = 0x0020, + CPRDYL = 0x0100, PRNT = 0x0200, CBSY = 0x0400, SC = 0x0800, + SCLK = 0x1000, VSYNC = 0x2000, +}; + +#define DPRINT kprint + +#define LBPDEV ((Lbpfifo *)&PORT[56]) + +static ushort csrwval; + +#define CSRW(val) (dev->csr = csrwval = (val)) +#define CSRSET(val) (dev->csr = csrwval |= (val)) +#define CSRCLR(val) (dev->csr = csrwval &= ~(val)) + +#define CMDW(val) (csrwval &= ~(CBSY|SC|SCLK), CSRSET(val)) + +enum { + Inited = 1, + Cmdlocked=2, + Bitlocked=4, + Bitmapped=8 +}; + +typedef struct Lbp { + int fifosize; + ulong flags; + Lock mlock; /* monitor proc active */ + Rendez ready; /* to wake monitor proc */ + QLock cmdlock; /* to send commands */ + int cmdreply; + QLock pagelock; /* to print */ + Rendez printing; /* to wake printing proc */ + Rectangle rect; /* page size */ + ulong *left, lmask, rmask; + int nhblank, width, nvblank, nlines; + Segment *s; /* bitmap may not span segments (BUG) */ + Page *xmap[256]; + Page **x, **xend; + KMap *kmap; + int ihl, maxhl, lcount; + long startclicks, stopclicks; +} Lbp; + +enum Lbpsize { + NHBLANK = 255, NVBLANK = 84, + LBPXMAX = 2424, LBPYMAX = 3262, LBPDOTS = 300, +}; + +typedef struct Lbpconf { + int nhblank, nvblank, xmax, ymax, res; +} Lbpconf; + +static Lbpconf lbpiconf = { + NHBLANK, NVBLANK, LBPXMAX, LBPYMAX, LBPDOTS, +}; +static Lbpconf lbpconf; +static Lbp lbp; +static int cprint0, cprint1; +static ulong pingval; + +enum { + Qdir, Qconf, Qdcmd, Qrcmd, Qmon, Qping, Qbit, Qpage +}; + +Dirtab lbpdir[]={ + "conf", {Qconf}, sizeof(Lbpconf), 0666, + "dcmd", {Qdcmd}, 1, 0666, + "rcmd", {Qrcmd}, 1, 0666, + "mon", {Qmon}, 0, 0666, + "ping", {Qping}, 0, 0666, + "bit", {Qbit}, 0, 0666, + "page", {Qpage}, 0, 0666 +}; +#define NLBP (sizeof lbpdir/sizeof(Dirtab)) + +static int lbpcmd(int); +static long lbppage(Point, GBitmap *, Rectangle); +static void lbpmap(Point, GBitmap *, Rectangle); +static Page * addr2page(ulong); +static void validbitmap(GBitmap *); +static int fillfifo(int); +static int lbpintr(void); + +static void +lbpsetconf(Lbpconf *cp) +{ + lbpconf = *cp; + lbp.rect.max.x = lbpconf.xmax; + lbp.rect.max.y = lbpconf.ymax; + return; +} + +void +lbpreset(void) +{ + lbpsetconf(&lbpiconf); +} + +void +lbpinit(void) +{} + +Chan * +lbpattach(char *param) +{ + Lbpfifo *dev = LBPDEV; + int i, hsize=0, fsize=0; + + addportintr(lbpintr); + if(lbp.fifosize<=0){ + CSRCLR(VCLRL); + CSRSET(VCLRL); + for(i=0; i<20000; i+=4){ + dev->fifo = 0; + if(!hsize && (dev->csr&HFL) == 0) + hsize = i+4; + if((dev->csr&FFL) == 0){ + fsize = i+4; + break; + } + } + /*pprint("lbpattach: hsize=%d, fsize=%d\n", hsize, fsize);*/ + lbp.fifosize = fsize; + } + return devattach('l', param); +} + +Chan * +lbpclone(Chan *c, Chan *nc) +{ + return devclone(c, nc); +} + +int +lbpwalk(Chan *c, char *name) +{ + return devwalk(c, name, lbpdir, NLBP, devgen); +} + +void +lbpstat(Chan *c, char *db) +{ + devstat(c, db, lbpdir, NLBP, devgen); +} + +Chan * +lbpopen(Chan *c, int omode) +{ + switch ((int)(c->qid.path & ~CHDIR)) { + /*case Qcmd:*/ + case Qbit: + case Qpage: + if (!(lbp.flags & Inited)) { + lbp.cmdreply = lbpcmd(0x40); + lbp.flags |= Inited; + } + break; + } + return devopen(c, omode, lbpdir, NLBP, devgen); +} + +void +lbpcreate(Chan *c, char *name, int omode, ulong perm) +{ + USED(c, name, omode, perm); + error(Eperm); +} + +void +lbpclose(Chan *c) +{ + USED(c); +} + +long +lbpread(Chan *c, void *va, long n, ulong offset) +{ + uchar *a = (uchar *)va; + if (n == 0) + return 0; + switch ((int)(c->qid.path & ~CHDIR)) { + case Qdir: + return devdirread(c, va, n, lbpdir, NLBP, devgen); + case Qconf: + if (offset >= 20) + return 0; + if (n < 20) + error(Etoosmall); + PLONG(&a[ 0], lbpconf.nhblank); + PLONG(&a[ 4], lbpconf.nvblank); + PLONG(&a[ 8], lbpconf.xmax); + PLONG(&a[12], lbpconf.ymax); + PLONG(&a[16], lbpconf.res); + n = 20; + break; + case Qdcmd: + *a = cprint1; + n = 1; + break; + case Qrcmd: + if (lbp.cmdreply > 0) + *a = lbp.cmdreply, n = 1; + else + n = 0; + break; + case Qmon: + if (canlock(&lbp.mlock)) { + sleep(&lbp.ready, return0, 0); + unlock(&lbp.mlock); + } else + error(Einuse); + n = 0; + break; + case Qping: + if (n != sizeof(ulong)) + n = 0; + else + *(ulong *)a = pingval; + break; + case Qbit: + case Qpage: + n = 0; + break; + } + return n; +} + +#define OKRECT(r) ((r).min.x<(r).max.x && (r).min.y<(r).max.y) +#define PTINRECT(p, r) ((r).min.x<=(p).x && (r).min.y<=(p).y && \ + (p).x<=(r).max.x && (p).y<=(r).max.y) +#define RINRECT(r, s) (PTINRECT((r).min, s) && PTINRECT((r).max, s)) + +long +lbpwrite(Chan *c, void *va, long n, ulong offset) +{ + uchar *a = (uchar *)va; + extern GBitmap *id2bit(int); + Point p; GBitmap *bp; Rectangle r; + Lbpconf tc; + int k, m = 0; + if (n == 0) + return 0; + switch ((int)c->qid.path) { + case Qconf: + if (offset >= 20) + return 0; + if (n < 20) + error(Etoosmall); + tc.nhblank = GLONG(&a[ 0]); + tc.nvblank = GLONG(&a[ 4]); + tc.xmax = GLONG(&a[ 8]); + tc.ymax = GLONG(&a[12]); + tc.res = GLONG(&a[16]); + lbpsetconf(&tc); + m = 20; + break; + case Qdcmd: + cprint1 = *a ? PRNT : 0; + m = 1; + break; + case Qrcmd: + lbp.cmdreply = lbpcmd(*a); + m = 1; + break; + case Qmon: + wakeup(&lbp.ready); + m = 0; + break; + case Qping: + if (n != sizeof(ulong)) + m = 0; + else { + Lbpfifo *dev = LBPDEV; + dev->fifo = *(ulong *)a; + pingval = dev->fifo; + m = sizeof(ulong); + } + break; + case Qbit: + case Qpage: + if (n != 28) + error(Ebadarg); + p.x = GLONG(&a[0]); + p.y = GLONG(&a[4]); + if (c->qid.path == Qbit) + bp = id2bit(GLONG(&a[8])); + else { + bp = (GBitmap *)GLONG(&a[8]); + validbitmap(bp); + } + r.min.x = GLONG(&a[12]); + r.min.y = GLONG(&a[16]); + r.max.x = GLONG(&a[20]); + r.max.y = GLONG(&a[24]); + DPRINT("lbpwrite: ckpage..."); + if ((k = lbp.rect.min.x - p.x) > 0) + r.min.x += k, p.x += k; + if ((k = lbp.rect.min.y - p.y) > 0) + r.min.y += k, p.y += k; + if ((k = Dx(r) + p.x - lbp.rect.max.x) > 0) + r.max.x -= k; + if ((k = Dy(r) + p.y - lbp.rect.max.y) > 0) + r.max.y -= k; + if (!OKRECT(r) || !RINRECT(r, bp->r)) + error(Ebadblt); + DPRINT("OK\n"); + m = lbppage(p, bp, r); + /*pprint("lbpwrite: %d clicks\n", m);*/ + break; + default: + panic("lbpwrite"); + } + return m; +} + +void +lbpremove(Chan *c) +{ + USED(c); + error(Eperm); +} + +void +lbpwstat(Chan *c, char *dp) +{ + USED(c, dp); + error(Eperm); +} + +static short poot, hoot; +#define MICROSECOND (poot=0, hoot=0); USED(poot, hoot) +#define TLIMIT 0x3fffff + +static void +lbpwait(int set, int clear, long timeout) +{ + Lbpfifo *dev = LBPDEV; + int status; long i=0; + + if(timeout <= 0) + timeout = TLIMIT; + timeout += m->ticks; + do{ + status = dev->csr; + if((status & set) == set && (status & clear) == 0){ + DPRINT("OK lbpwait(pid=%d,i=%d)...", u->p->pid, i); + return; + } + if((i++ % 32768) == 0) + DPRINT("lbpwait(pid=%d,i=%d)...", u->p->pid, i-1); + sched(); + if(u->p->notepending){ + u->p->notepending = 0; + DPRINT("intr lbpwait(pid=%d,i=%d)\n", u->p->pid, i); + error(Eintr); + } + }while(m->ticks < timeout); + DPRINT("timeout lbpwait(pid=%d,i=%d)\n", u->p->pid, i); + error(Eio); +} + +static int +lbpcmd(int cmd) +{ + Lbpfifo *dev = LBPDEV; + int mask = 0x80, status; + + qlock(&lbp.cmdlock); + if (waserror()) { + qunlock(&lbp.cmdlock); + nexterror(); + } + lbpwait(0, (PPRDYL|SBSY|SC|SCLK), 600); + + CMDW(CBSY); /* cbsy asserted */ + do { + if (cmd & mask) { + CMDW(CBSY|SCLK|SC); /* clock up, data 1 */ + MICROSECOND; + CMDW(CBSY|SC); /* clock down, data 1 */ + MICROSECOND; + } else { + CMDW(CBSY|SCLK); /* clock up, data 0 */ + MICROSECOND; + CMDW(CBSY); /* clock down, data 0 */ + MICROSECOND; + } + } while (mask >>= 1); + CMDW(0); /* release cbsy, clock, data */ + + lbpwait(SBSY, 0, 120); /* wait for sbsy */ + sched(); /* wait >1 msec */ + + status = 0; + mask = 0x80; do { + int temp; + CMDW(SCLK); /* clock up */ + MICROSECOND; + CMDW(0); /* clock down */ + MICROSECOND; + temp = dev->csr; + if (temp & SC) + status |= mask; + } while (mask >>= 1); + + DPRINT("lbp: cmd = 0x%x, status = 0x%x\n", cmd, status); + poperror(); + qunlock(&lbp.cmdlock); + return status; +} + +#define WORDSIZE 32 + +/*extern ulong _topbits[];*/ + +static ulong _topbits[]={ + 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, + 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, + 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, + 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, + 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, + 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, + 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, + 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe, + 0xffffffff, +}; + +#define PBASE(va) (((ulong)(va)) & ~(BY2PG-1)) +#define POFFSET(va) (((ulong)(va)) & (BY2PG-1)) + +static void +lbpmap(Point p, GBitmap *bp, Rectangle r) +{ + ulong *left, *right; ulong j; + int i, lbits, rbits; + + if ((lbits = r.min.x%WORDSIZE) < 0) + lbits += WORDSIZE; + if ((rbits = r.max.x%WORDSIZE) < 0) + rbits += WORDSIZE; + lbp.lmask = lbits ? ~_topbits[lbits] : 0; + lbp.rmask = rbits ? _topbits[rbits] : 0; + lbp.nhblank = 0xff00-(lbpconf.nhblank - lbits + p.x); + if (lbp.nhblank < 0) + lbp.nhblank = 0; + else if (lbp.nhblank > 0xfeff) + lbp.nhblank = 0xfeff; + left = gaddr(bp, r.min); + right = gaddr(bp, Pt(r.max.x-1, r.min.y)); + lbp.left = left; + lbp.maxhl = right - left; + lbp.width = bp->width; + lbp.nvblank = lbpconf.nvblank + p.y; + lbp.nlines = lbp.nvblank + Dy(r); + DPRINT("lbpmap: nvblank=%d, nlines=%d\n", lbp.nvblank, lbp.nlines); + lbp.ihl = 0; + lbp.lcount = 0; + + lbp.x = lbp.xend = lbp.xmap; + lbp.s = 0; + if (ISKVA(left)) + return; + lbp.s = seg(u->p, (ulong)left, 1); + if (!lbp.s) + error(Ebadarg); + lbp.s->steal++; + qunlock(&lbp.s->lk); + if (waserror()){ + qlock(&lbp.s->lk); + lbp.s->steal--; + qunlock(&lbp.s->lk); + error(Ebadarg); + } + + for (i=r.min.y; iwidth, right+=bp->width) { + for (j=PBASE(left); j<=PBASE(right); j+=BY2PG) { + if (lbp.xend > lbp.xmap && j <= lbp.xend[-1]->va) + continue; + /*DPRINT("probing 0x%lux\n", j);*/ + *lbp.xend++ = addr2page(j); + } + } + poperror(); +} + +Page * +addr2page(ulong addr) +{ + Segment *s; long soff; Pte *pte; Page *pg = 0; + + poot = *(ulong *)addr; /* fault it if necessary */ + s = seg(u->p, addr, 1); + if(s != lbp.s) + error(Ebadarg); + soff = addr-s->base; + pte = s->map[soff/PTEMAPMEM]; + if(pte) + pg = pte->pages[(soff&(PTEMAPMEM-1))/BY2PG]; + + if(pg == 0){ + qunlock(&s->lk); + pprint("nonresident page addr %lux (complain to rob)\n", addr); + error(Eio); + } + qunlock(&s->lk); + return pg; +} + +static void +validbitmap(GBitmap *bp) +{ + ulong tl, br; + validaddr((ulong)bp, sizeof(GBitmap), 0); + if (((ulong)bp->base&3) || bp->width<=0 || bp->ldepth!=0 || !OKRECT(bp->r)) + error(Ebadbitmap); + tl = (ulong)gaddr(bp, bp->r.min); + br = (ulong)gaddr(bp, bp->r.max); + validaddr(tl, br-tl, 0); +} + +static long +lbppage(Point p, GBitmap *bp, Rectangle r) +{ + extern QLock bitlock; + Lbpfifo *dev = LBPDEV; + long dt; + + if (csrwval & (PRNT|GO)) { + cprint0 = PRNT; + if (!(csrwval & PRNT)) + CSRSET(PRNT); + } + DPRINT("lbppage: qlock %d...\n", u->p->pid); + qlock(&lbp.pagelock); + DPRINT("...%d OK\n", u->p->pid); + if(waserror()){ + if(lbp.flags & Bitmapped){ + lbp.flags &= ~Bitmapped; + kunmap(lbp.kmap); + qlock(&lbp.s->lk); + lbp.s->steal--; + qunlock(&lbp.s->lk); + } + if(lbp.flags & Bitlocked){ + lbp.flags &= ~Bitlocked; + qunlock(&bitlock); + } + if(lbp.flags & Cmdlocked){ + lbp.flags &= ~Cmdlocked; + qunlock(&lbp.cmdlock); + } + qunlock(&lbp.pagelock); + nexterror(); + } + cprint0 = lbp.pagelock.head ? PRNT : 0; + + if (dev->csr & PPRDYL) { + CSRW(0); + pprint("printer power not ready\n"); + error(Eio); + } + if (!(dev->csr & RDY)) { + DPRINT("lbpprt: not ready, waiting..."); + wakeup(&lbp.ready); + lbpwait(RDY, 0, 0x7fffffffL); /* wait for rdy */ + DPRINT("OK\n"); + } + + qlock(&lbp.cmdlock); + lbp.flags |= Cmdlocked; + if(ISKVA(bp->base)){ + qlock(&bitlock); + lbp.flags |= Bitlocked; + } + lbpmap(p, bp, r); + if(!ISKVA(bp->base)){ + lbp.kmap = kmap(lbp.xmap[0]); + lbp.flags |= Bitmapped; + } + DPRINT("lbpprt: filling fifo..."); + CSRCLR(VCLRL); /* clear fifo */ + CSRSET(VCLRL); + dev->hblank = lbp.nhblank; /* left margin */ + if (fillfifo(lbp.fifosize)) /* did all the data fit ? */ + CSRSET(EFINTEN); /* yes, interrupt when fifo empty */ + else + CSRSET(HFINTEN|EFINTEN);/* no, interrupt when half-empty */ + DPRINT("OK\n"); + CSRSET(PRNT); /* assert prnt */ + DPRINT("(PRNT 0x%4.4x)...", csrwval); + lbpwait(VSREQ, 0, 0L); /* wait for vsreq */ + DPRINT("VSREQ+..."); + + DPRINT("(VSYNC)..."); + CSRSET(VSYNC); /* now give him vsync */ + + lbpwait(0, VSREQ, 0L); /* wait for ack (vsreq goes away) */ + DPRINT("VSREQ-..."); + csrwval &= ~(FOURHDPI|PRNT|VSYNC); + if (lbpconf.res == 400) + CSRSET(FOURHDPI|cprint0|cprint1|GO); + else + CSRSET(cprint0|cprint1|GO); + DPRINT("lbpprt: ready, ticks=%d\n", m->ticks); + qunlock(&lbp.cmdlock); + lbp.flags &= ~Cmdlocked; + lbp.startclicks = 0; + lbp.stopclicks = 0; + sleep(&lbp.printing, return0, 0); + if(ISKVA(bp->base)){ + qunlock(&bitlock); + lbp.flags &= ~Bitlocked; + }else{ + kunmap(lbp.kmap); + qlock(&lbp.s->lk); + lbp.s->steal--; + qunlock(&lbp.s->lk); + lbp.flags &= ~Bitmapped; + } + dt = lbp.stopclicks - lbp.startclicks; + DPRINT("lbpprt: lcount=%d, nlines=%d\n", lbp.lcount, lbp.nlines); + DPRINT("lbpprt: start=%d, stop=%d, dt=%d\n", + lbp.startclicks, lbp.stopclicks, dt); + qunlock(&lbp.pagelock); + poperror(); + return dt; +} + +static int +fillfifo(int nfifo) +{ + Lbpfifo *dev = LBPDEV; + ulong *up, *kp; + int nout, npg; + if (lbp.lcount < lbp.nvblank) { + nout = lbp.nvblank - lbp.lcount; + if (nout > nfifo) + nout = nfifo; + nfifo -= nout; + lbp.lcount += nout; + CSRSET(EOL); + while (--nout >= 0) + *(char *)&dev->fifo = 0; + CSRCLR(EOL); + } + while (nfifo > sizeof(ulong)) { + up = lbp.left + lbp.ihl; + if (ISKVA(up)) + kp = up; + else { + while (PBASE(up) > (*lbp.x)->va) + ++lbp.x; + lbp.kmap->pa = (*lbp.x)->pa; + putkmmu(lbp.kmap->va, PPN(lbp.kmap->pa) | PTEVALID | PTEKERNEL); + kp = (ulong *)(lbp.kmap->va + POFFSET(up)); + } + if (lbp.ihl == 0 && lbp.lmask) { + dev->fifo = *kp & lbp.lmask; + ++lbp.ihl, nfifo -= sizeof(ulong); + } else if (lbp.ihl == lbp.maxhl && lbp.rmask) { + dev->fifo = *kp & lbp.rmask; + ++lbp.ihl, nfifo -= sizeof(ulong); + } else { + nout = lbp.maxhl - lbp.ihl + (lbp.rmask == 0); + npg = (BY2PG - POFFSET(up))/BY2WD; + if (nout > npg) + nout = npg; + if (nout > nfifo/sizeof(ulong)) + nout = nfifo/sizeof(ulong); + lbp.ihl += nout; + nfifo -= nout*sizeof(ulong); + while(--nout >= 0) + dev->fifo = *kp++; + } + if (lbp.ihl > lbp.maxhl) { + CSRSET(EOL); + *(char *)&dev->fifo = 0; + CSRCLR(EOL); + --nfifo; + lbp.ihl = 0; + lbp.left += lbp.width; + if (++lbp.lcount >= lbp.nlines) + return 1; + } + } + return 0; +} + +/*static int +fillfifo(int nfifo) +{ + Lbpfifo *dev = LBPDEV; + ulong *up; + int nout, npg; + if (lbp.lcount < lbp.nvblank) { + nout = lbp.nvblank - lbp.lcount; + if (nout > nfifo) + nout = nfifo; + nfifo -= nout; + lbp.lcount += nout; + CSRSET(EOL); + while (--nout >= 0) + *(char *)&dev->fifo = 0; + CSRCLR(EOL); + } + while (nfifo > sizeof(ulong)) { + up = lbp.left + lbp.ihl; + if (lbp.ihl == 0 && lbp.lmask) { + dev->fifo = *up & lbp.lmask; + ++lbp.ihl, nfifo -= sizeof(ulong); + } else if (lbp.ihl == lbp.maxhl && lbp.rmask) { + dev->fifo = *up & lbp.rmask; + ++lbp.ihl, nfifo -= sizeof(ulong); + } else { + nout = lbp.maxhl - lbp.ihl + (lbp.rmask == 0); + if (nout > nfifo/sizeof(ulong)) + nout = nfifo/sizeof(ulong); + lbp.ihl += nout; + nfifo -= nout*sizeof(ulong); + while (--nout >= 0) + dev->fifo = *up++; + } + if (lbp.ihl > lbp.maxhl) { + CSRSET(EOL); + *(char *)&dev->fifo = 0; + CSRCLR(EOL); + --nfifo; + lbp.ihl = 0; + lbp.left += lbp.width; + if (++lbp.lcount >= lbp.nlines) + return 1; + } + } + return 0; +} +*/ + +static int +lbpintr(void) +{ + Lbpfifo *dev = LBPDEV; + ushort csr = dev->csr; + if (!(csr & BINT)) { + /*print("lbpintr: no BINT 0x%x\n", csr);*/ + return 1/*0*/; + } + if (!lbp.printing.p) { + CSRCLR(HFINTEN|EFINTEN|GO); + print("spurious lbpintr: 0x%4.4ux\n", csr); + return 1; + } + if (!(csr & EFL)) { + lbp.stopclicks = m->ticks; + CSRCLR(HFINTEN|EFINTEN|GO); + wakeup(&lbp.printing); + } else if (csr & HFL) { + if (!lbp.startclicks) + lbp.startclicks = m->ticks; + if (fillfifo(lbp.fifosize/2)) { /* did all the data fit ? */ + csrwval &= ~HFINTEN; + CSRSET(EFINTEN); /* yes, interrupt when fifo empty */ + } + } else { + print("null lbpintr: 0x%4.4ux\n", csr); + } + return 1; +} diff --git a/port/devbit.c b/port/devbit.c index 3a4df96c8527d82060c43fbcdb71be77405ad853..eab275bc36d568f8885be84242977f30f7d60fc0 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -1723,12 +1723,25 @@ bitloadchar(GFont *f, int ci, GSubfont *subf, int si) gbitblt(f->b, Pt(c->x, f->ascent-subf->ascent), subf->bits, rect, S); } +QLock bitlock; + +GBitmap* +id2bit(int v) +{ + GBitmap *bp=0; + + if(v<0 || v>=bit.nmap || (bp=bit.map[v])==0) + error(Ebadbitmap); + return bp; +} + void bitcompact(void) { Arena *a, *ea, *na; ulong *p1, *p2, n; + qlock(&bitlock); ea = &bit.arena[bit.narena]; for(a=bit.arena; awords == 0) @@ -1782,6 +1795,7 @@ bitcompact(void) for(a=bit.arena; awords && a->nbusy==0) arenafree(a); + qunlock(&bitlock); } void diff --git a/ss/main.c b/ss/main.c index 037984abb832a98ceecb9f2a3702b1eb4a1200cb..10ec40f7f8e99c9e1ea1dd45ee3e33ded95aeee7 100644 --- a/ss/main.c +++ b/ss/main.c @@ -40,8 +40,8 @@ sysparam[] = { 0x53, "1+ 4/65", 0, 65536, 16, 8, 128, 0, 64 }, { 0x54, "SLC 4/20", 0, 65536, 16, 8, 128, 0, 64 }, { 0x55, "2 4/75", 1, 65536, 32, 16, 256, 1, 64 }, - { 0x56, "ELC 4/25", 1, 65536, 32, 16, 256, 1, 64 }, - { 0x57, "IPX 4/50", 1, 65536, 32, 16, 256, 1, 64 }, + { 0x56, "ELC 4/25", 1, 65536, 32, 8, 128, 1, 64 }, + { 0x57, "IPX 4/50", 1, 65536, 32, 8, 256, 1, 64 }, { 0 } }; Sysparam *sparam;