From ee8c5059d684c36222065cd21b857fab9843117b Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 7 Oct 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-10-07 --- pc/devusb.c | 74 +++-------- pc/io.h | 1 + pc/vgat2r4.c | 329 ++++++++++++++++++++++++++++++++++++++++++++++++ port/segment.c | 2 + port/thwack.c | 81 ++++-------- port/thwack.h | 14 +-- port/unthwack.c | 162 +++++++++--------------- 7 files changed, 440 insertions(+), 223 deletions(-) create mode 100644 pc/vgat2r4.c diff --git a/pc/devusb.c b/pc/devusb.c index 42f8edb9a2e3395d8faa7d3805a60db1eea3bc83..7580441b28694205ccc71fd829b82759eafcc711 100644 --- a/pc/devusb.c +++ b/pc/devusb.c @@ -369,9 +369,9 @@ dumptd(TD *t, int follow) if(t->status & LowSpeed) *s++ = 'L'; *s = 0; - print("td %8.8lux: l=%8.8lux s=%8.8lux d=%8.8lux b=%8.8lux %8.8lux f=%8.8lux\n", + XPRINT("td %8.8lux: l=%8.8lux s=%8.8lux d=%8.8lux b=%8.8lux %8.8lux f=%8.8lux\n", t, t->link, t->status, t->dev, t->buffer, t->bp?(ulong)t->bp->rp:0, t->flags); - print("\ts=%s,ep=%ld,d=%ld,D=%ld\n", buf, (t->dev>>15)&0xF, (t->dev>>8)&0xFF, (t->dev>>19)&1); + XPRINT("\ts=%s,ep=%ld,d=%ld,D=%ld\n", buf, (t->dev>>15)&0xF, (t->dev>>8)&0xFF, (t->dev>>19)&1); if(t->bp) dumpdata(t->bp, n); if(!follow || t->link & Terminate || t->link & IsQH) @@ -401,44 +401,6 @@ alloctde(Endpt *e, int pid, int n) return t; } -static TD * -alloctdring(int nbuf, Endpt *e, int pid, int maxn) -{ - TD *t, *lt, *ft; - int id, i; - ulong status, dev; - - if(!e->iso) - nbuf = (nbuf+1)&~1; - id = (e->x<<7)|(e->dev->x&0x7F); - dev = ((maxn-1)<<21) | ((id&0x7FF)<<8) | pid; - status = 0; - if(e->dev->ls) - status |= LowSpeed; - ft = lt = nil; - for(i=0; iep = e; - t->status = status; - t->dev = dev; - if(!e->iso) - dev ^= IsDATA1; - if(pid == TokIN){ - t->bp = allocb(maxn); - t->buffer = PADDR(t->bp->wp); - } - if(ft != nil){ - lt->next = t; - lt->link = PADDR(t); - }else - ft = t; - lt = t; - } - if(lt != nil) - lt->link = PADDR(ft); /* loop to form ring */ - return ft; -} - static QH * allocqh(Ctlr *ub) { @@ -475,13 +437,13 @@ dumpqh(QH *q) q0 = q; for(i = 0; q != nil && i < 10; i++){ - pprint("qh %8.8lux: %8.8lux %8.8lux\n", q, q->head, q->entries); + XPRINT("qh %8.8lux: %8.8lux %8.8lux\n", q, q->head, q->entries); if((q->entries & Terminate) == 0) dumptd(TFOL(q->entries), 1); if(q->head & Terminate) break; if((q->head & IsQH) == 0){ - pprint("head:"); + XPRINT("head:"); dumptd(TFOL(q->head), 1); break; } @@ -525,7 +487,7 @@ cleantd(TD *t, int discard) err = t->status & (AnyError&~NAKed); /* TO DO: on t->status&AnyError, q->entries will not have advanced */ if (err) - print("cleanTD: Error %8.8lux %8.8lux %8.8lux %8.8lux\n", t->link, t->status, t->dev, t->buffer); + XPRINT("cleanTD: Error %8.8lux %8.8lux %8.8lux %8.8lux\n", t->link, t->status, t->dev, t->buffer); switch(t->dev&0xFF){ case TokIN: if(discard || (t->flags & CancelTD) || t->ep == nil || t->ep->x!=0&&err){ @@ -624,7 +586,7 @@ canceltds(Ctlr *ub, QH *q, Endpt *e) if(t->ep == e) t->flags |= CancelTD; iunlock(ub); - pprint("cancel:\n"); + XPRINT("cancel:\n"); dumpqh(q); } } @@ -805,7 +767,7 @@ mkqhtree(ulong *frame, int framesize, int maxms) o |= 1; } if(leaf0+o >= n){ - pprint("leaf0=%d o=%d i=%d n=%d\n", leaf0, o, i, n); + XPRINT("leaf0=%d o=%d i=%d n=%d\n", leaf0, o, i, n); break; } frame[i] = PADDR(&tree[leaf0+o]) | IsQH; @@ -828,14 +790,14 @@ dumpframe(int f, int t) if(t < 0) t = 32; for(i=f; ihead); + XPRINT("F%.2d %8.8lux %8.8lux\n", i, frame[i], QFOL(frame[i])->head); for(p=frame[i]; (p & IsQH) && (p &Terminate) == 0; p = q->head){ q = QFOL(p); if(!(q >= tree && q < &tree[n])){ - pprint("Q: p=%8.8lux out of range\n", p); + XPRINT("Q: p=%8.8lux out of range\n", p); break; } - pprint(" -> %8.8lux h=%8.8lux e=%8.8lux\n", p, q->head, q->entries); + XPRINT(" -> %8.8lux h=%8.8lux e=%8.8lux\n", p, q->head, q->entries); } } } @@ -1104,9 +1066,9 @@ interrupt(Ureg*, void *a) ub = a; s = IN(Status); if (s & 0x1a) { - print("usbint: #%x f%d\n", s, IN(Frnum)); - print("cmd #%x sofmod #%x\n", IN(Cmd), inb(ub->io+SOFMod)); - print("sc0 #%x sc1 #%x\n", IN(Portsc0), IN(Portsc1)); + XPRINT("usbint: #%x f%d\n", s, IN(Frnum)); + XPRINT("cmd #%x sofmod #%x\n", IN(Cmd), inb(ub->io+SOFMod)); + XPRINT("sc0 #%x sc1 #%x\n", IN(Portsc0), IN(Portsc1)); } OUT(Status, s); @@ -1570,7 +1532,7 @@ readusb(Endpt *e, void *a, long n) p = a; do { if(e->eof) { - pprint("e->eof\n"); + XPRINT("e->eof\n"); break; } if(e->err) @@ -1583,7 +1545,7 @@ readusb(Endpt *e, void *a, long n) error(e->err); b = qget(e->rq); /* TO DO */ if(b == nil) { - pprint("b == nil\n"); + XPRINT("b == nil\n"); break; } if(waserror()){ @@ -1846,7 +1808,7 @@ usbwrite(Chan *c, void *a, long n, vlong) /* ep n maxpkt mode poll nbuf */ i = strtoul(fields[1], nil, 0); if(i < 0 || i >= nelem(d->ep)) { - pprint("field 1: 0 <= %d < %d\n", i, nelem(d->ep)); + XPRINT("field 1: 0 <= %d < %d\n", i, nelem(d->ep)); error(Ebadarg); } if(d->ep[i] != nil) @@ -1869,7 +1831,7 @@ usbwrite(Chan *c, void *a, long n, vlong) if(i > 0 && i <= 1000) e->pollms = i; else { - pprint("field 4: 0 <= %d <= 1000\n", i); + XPRINT("field 4: 0 <= %d <= 1000\n", i); error(Ebadarg); } } @@ -1878,7 +1840,7 @@ usbwrite(Chan *c, void *a, long n, vlong) e->nbuf = i; poperror(); }else { - pprint("command %s, fields %d\n", fields[0], nf); + XPRINT("command %s, fields %d\n", fields[0], nf); error(Ebadarg); } return n; diff --git a/pc/io.h b/pc/io.h index c2092e5ee872c74b8ce0db8f01eaef4c2b343f64..38dd62de3fe29c2e7cb68044fe55bef057123845 100644 --- a/pc/io.h +++ b/pc/io.h @@ -5,6 +5,7 @@ enum { VectorNMI = 2, /* non-maskable interrupt */ VectorBPT = 3, /* breakpoint */ + VectorUD = 6, /* invalid opcode exception */ VectorCNA = 7, /* coprocessor not available */ VectorCSO = 9, /* coprocessor segment overrun */ VectorPF = 14, /* page fault */ diff --git a/pc/vgat2r4.c b/pc/vgat2r4.c new file mode 100644 index 0000000000000000000000000000000000000000..e28bdf2840331f36f25a923024179b50a26a27f1 --- /dev/null +++ b/pc/vgat2r4.c @@ -0,0 +1,329 @@ +#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 +#include +#include +#include "screen.h" + +/* + * #9 Ticket to Ride IV. + */ +enum { + IndexLo = 4, + IndexHi = 5, + Data = 6, + IndexCtl = 7, +}; + +enum { /* index registers */ + CursorCtl = 0x30, + CursorXLo = 0x31, + CursorXHi = 0x32, + CursorYLo = 0x33, + CursorYHi = 0x34, + CursorHotX = 0x35, + CursorHotY = 0x36, + + CursorR1 = 0x40, + CursorG1 = 0x41, + CursorB1 = 0x42, + CursorR2 = 0x43, + CursorG2 = 0x44, + CursorB2 = 0x45, + CursorR3 = 0x46, + CursorG3 = 0x47, + CursorB3 = 0x48, + + CursorArray = 0x100, +}; + +static ulong +t2r4linear(VGAscr* scr, int* size, int* align) +{ + ulong aperture, oaperture; + int oapsize, wasupamem; + Pcidev *p; + + oaperture = scr->aperture; + oapsize = scr->apsize; + wasupamem = scr->isupamem; + + aperture = 0; + if(p = pcimatch(nil, 0x105D, 0)){ + switch(p->did){ + case 0x5348: + aperture = p->mem[0].bar & ~0x0F; + *size = p->mem[0].size; + break; + default: + break; + } + } + + if(wasupamem){ + if(oaperture == aperture) + return oaperture; + upafree(oaperture, oapsize); + } + scr->isupamem = 0; + + aperture = upamalloc(aperture, *size, *align); + if(aperture == 0){ + if(wasupamem && upamalloc(oaperture, oapsize, 0)){ + aperture = oaperture; + scr->isupamem = 1; + } + else + scr->isupamem = 0; + } + else + scr->isupamem = 1; + + return aperture; +} + +static void +t2r4enable(VGAscr* scr) +{ + Pcidev *p; + Physseg seg; + int size, align; + ulong aperture; + + /* + * Only once, can't be disabled for now. + * scr->io holds the virtual address of + * the MMIO registers. + */ + if(scr->io) + return; + if(p = pcimatch(nil, 0x105D, 0)){ + switch(p->did){ + case 0x5348: + break; + default: + return; + } + } + else + return; + scr->io = upamalloc(p->mem[4].bar & ~0x0F, p->mem[4].size, 0); + if(scr->io == 0) + return; + + memset(&seg, 0, sizeof(seg)); + seg.attr = SG_PHYSICAL; + seg.name = smalloc(NAMELEN); + snprint(seg.name, NAMELEN, "t2r4mmio"); + seg.pa = scr->io; + seg.size = p->mem[4].size; + addphysseg(&seg); + + scr->io = (ulong)KADDR(scr->io); + + size = p->mem[0].size; + align = 0; + aperture = t2r4linear(scr, &size, &align); + if(aperture){ + scr->aperture = aperture; + scr->apsize = size; + memset(&seg, 0, sizeof(seg)); + seg.attr = SG_PHYSICAL; + seg.name = smalloc(NAMELEN); + snprint(seg.name, NAMELEN, "t2r4screen"); + seg.pa = aperture; + seg.size = size; + addphysseg(&seg); + } +} + +static void +t2r4xo(VGAscr* scr, int index, uchar data) +{ + ulong *mmio; + + mmio = (ulong*)scr->io; + mmio[IndexLo] = index & 0xFF; + mmio[IndexHi] = (index>>8) & 0xFF; + + mmio[Data] = data; +} + +static void +t2r4curdisable(VGAscr* scr) +{ + if(scr->io == 0) + return; + t2r4xo(scr, CursorCtl, 0x00); +} + +static void +t2r4curload(VGAscr* scr, Cursor* curs) +{ + int x, y; + ulong *mmio; + uchar p, p0, p1; + + if(scr->io == 0) + return; + mmio = (ulong*)scr->io; + + /* + * Make sure cursor is off by initialising the cursor + * control to defaults. + */ + t2r4xo(scr, CursorCtl, 0x00); + + /* + * Set auto-increment mode for index-register addressing + * and initialise the cursor array index. + */ + mmio[IndexCtl] = 0x01; + mmio[IndexLo] = CursorArray & 0xFF; + mmio[IndexHi] = (CursorArray>>8) & 0xFF; + + /* + * Initialise the 32x32 cursor RAM array. There are 2 planes, + * p0 and p1. Data is written 4 pixels per byte, with p1 the + * MS bit of each pixel. + * The cursor is set in X-Windows mode which gives the following + * truth table: + * p1 p0 colour + * 0 0 underlying pixel colour + * 0 1 underlying pixel colour + * 1 0 cursor colour 1 + * 1 1 cursor colour 2 + * Put the cursor into the top-left of the 32x32 array. + */ + for(y = 0; y < 32; y++){ + for(x = 0; x < 32/8; x++){ + if(x < 16/8 && y < 16){ + p0 = curs->clr[x+y*2]; + p1 = curs->set[x+y*2]; + + p = 0x00; + if(p1 & 0x80) + p |= 0xC0; + else if(p0 & 0x80) + p |= 0x80; + if(p1 & 0x40) + p |= 0x30; + else if(p0 & 0x40) + p |= 0x20; + if(p1 & 0x20) + p |= 0x0C; + else if(p0 & 0x20) + p |= 0x08; + if(p1 & 0x10) + p |= 0x03; + else if(p0 & 0x10) + p |= 0x02; + mmio[Data] = p; + + p = 0x00; + if(p1 & 0x08) + p |= 0xC0; + else if(p0 & 0x08) + p |= 0x80; + if(p1 & 0x04) + p |= 0x30; + else if(p0 & 0x04) + p |= 0x20; + if(p1 & 0x02) + p |= 0x0C; + else if(p0 & 0x02) + p |= 0x08; + if(p1 & 0x01) + p |= 0x03; + else if(p0 & 0x01) + p |= 0x02; + mmio[Data] = p; + } + else{ + mmio[Data] = 0x00; + mmio[Data] = 0x00; + } + } + } + + /* + * Initialise the cursor hotpoint, + * enable the cursor and restore state. + */ + t2r4xo(scr, CursorHotX, -curs->offset.x); + t2r4xo(scr, CursorHotY, -curs->offset.y); + + t2r4xo(scr, CursorCtl, 0x23); +} + +static int +t2r4curmove(VGAscr* scr, Point p) +{ + if(scr->io == 0) + return 1; + + t2r4xo(scr, CursorXLo, p.x & 0xFF); + t2r4xo(scr, CursorXHi, (p.x>>8) & 0x0F); + t2r4xo(scr, CursorYLo, p.y & 0xFF); + t2r4xo(scr, CursorYHi, (p.y>>8) & 0x0F); + + return 0; +} + +static void +t2r4curenable(VGAscr* scr) +{ + t2r4enable(scr); + if(scr->io == 0) + return; + + /* + * Make sure cursor is off by initialising the cursor + * control to defaults. + */ + t2r4xo(scr, CursorCtl, 0x00); + + /* + * Cursor colour 1 (white), + * cursor colour 2 (black). + */ + t2r4xo(scr, CursorR1, Pwhite); + t2r4xo(scr, CursorG1, Pwhite); + t2r4xo(scr, CursorB1, Pwhite); + + t2r4xo(scr, CursorR2, Pblack); + t2r4xo(scr, CursorG2, Pblack); + t2r4xo(scr, CursorB2, Pblack); + + /* + * Load, locate and enable the cursor, 32x32, mode 2. + */ + t2r4curload(scr, &arrow); + t2r4curmove(scr, ZP); + t2r4xo(scr, CursorCtl, 0x23); +} + +VGAdev vgat2r4dev = { + "t2r4", + + t2r4enable, + nil, + nil, + t2r4linear, +}; + +VGAcur vgat2r4cur = { + "t2r4hwgc", + + t2r4curenable, + t2r4curdisable, + t2r4curload, + t2r4curmove, +}; diff --git a/port/segment.c b/port/segment.c index 66ef6bce2870c9ebc604c2bebe30281723990355..74fc66c4fe2b53e5695ceb89f9121a739d030517 100644 --- a/port/segment.c +++ b/port/segment.c @@ -612,6 +612,8 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len) error(Enovmem); len = PGROUND(len); + if(len == 0) + error(Ebadarg); /* * Find a hole in the address space. diff --git a/port/thwack.c b/port/thwack.c index f2e34912d80339a316802af57a5fe7ed01ef3af4..694870cc23b6b95277a3a381ee0b6d82fc0f8333 100644 --- a/port/thwack.c +++ b/port/thwack.c @@ -1,5 +1,5 @@ #include "u.h" -#include "../port/lib.h" +#include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" @@ -13,16 +13,17 @@ struct Huff ulong encode; /* the code */ }; -static Huff lentab[MaxLen] = +static Huff lentab[MaxFastLen] = { {1, 0x0}, /* 0 */ {2, 0x2}, /* 10 */ {4, 0xc}, /* 1100 */ {4, 0xd}, /* 1101 */ - {5, 0x1e}, /* 11110 */ - {6, 0x3e}, /* 111110 */ - {6, 0x3f}, /* 111111 */ - {4, 0xe}, /* 1110 */ + {5, 0x1c}, /* 11100 */ + {6, 0x3a}, /* 111010 */ + {6, 0x3b}, /* 111011 */ + {7, 0x78}, /* 1111000 */ + {7, 0x79}, /* 1111001 */ }; static void bitput(Thwack *tw, int c, int n); @@ -139,9 +140,9 @@ thwack(Thwack *tw, uchar *dst, uchar *src, int n, ulong seq) { ThwBlock *eblocks, *b, blocks[CompBlocks]; uchar *s, *ss, *sss, *esrc, *half; - ulong cont, cseq, bseq, cmask; + ulong cont, cseq, bseq, cmask, code; int now, toff; - int h, m, slot, bits, totmatched; + int h, m, slot, bits, use, totmatched; if(n > ThwMaxBlock || n < MinMatch || waserror()) return -1; @@ -227,11 +228,20 @@ thwack(Thwack *tw, uchar *dst, uchar *src, int n, ulong seq) bitput(tw, toff & ((1 << bits) - 1), bits); m -= MinMatch; - if(m < MaxLen-1){ + if(m < MaxFastLen){ bitput(tw, lentab[m].encode, lentab[m].bits); }else{ - bitput(tw, lentab[MaxLen-1].encode, lentab[MaxLen-1].bits); - iomegaput(tw, m - (MaxLen - 2)); + code = BigLenCode; + bits = BigLenBits; + use = BigLenBase; + m -= MaxFastLen; + while(m >= use){ + m -= use; + code = (code + use) << 1; + use <<= bits & 1; + bits++; + } + bitput(tw, (code + m), bits); } } blocks->maxoff += ss - s; @@ -274,52 +284,3 @@ bitput(Thwack *tw, int c, int n) *tw->dst++ = tw->bits >> (tw->nbits - 8); } } - -/* - * elias's omega code, modified - * for at least 3 bit transmission - */ -static Huff omegatab[16] = -{ - {0, 0}, /* 1 */ - {0, 0}, - {0, 0}, - {0, 0}, - {3, 0x4}, /* 5 */ - {3, 0x5}, - {3, 0x6}, - {3, 0x7}, - {7, 0x48}, - {7, 0x49}, /* 10 */ - {7, 0x4a}, - {7, 0x4b}, - {7, 0x4c}, - {7, 0x4d}, - {7, 0x4e}, /* 15 */ - {7, 0x4f}, -}; - -static int -iomegaput(Thwack *tw, ulong v) -{ - int b, bb; - - v--; - if(v < 4){ - bitput(tw, v, 3); - return 3; - } - if(v < 16){ - b = omegatab[v].bits + 1; - bitput(tw, omegatab[v].encode << 1, b); - return b; - } - - for(bb = 5; v >= (1 << bb); bb++) - ; - if(bb >= 16) - error("thwack omegaput"); - b = bb + omegatab[bb].bits + 1; - bitput(tw, (omegatab[bb].encode << (bb + 1)) | (v << 1), b); - return b; -} diff --git a/port/thwack.h b/port/thwack.h index 02443548ab915fcdf1e6ee1397c2f3ed96dae4ab..255205837305000a7218aa298893421e8783f853 100644 --- a/port/thwack.h +++ b/port/thwack.h @@ -12,11 +12,16 @@ enum HashSize = 1<blocks[i].data = ut->data[i]; } -/* - * to speed up, inline bitget - */ int unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) { UnthwBlock blocks[CompBlocks], *b, *eblocks; - uchar *s, *es, *d, *dmax; - ulong cmask, cseq, bseq, utbits, utnbits; - int off, len, bits, slot, tslot; + uchar *s, *es, *d, *dmax, *smax; + ulong cmask, cseq, bseq, utbits; + int off, len, bits, slot, tslot, use, code, utnbits, overbits; - if(nsrc < 4 || nsrc > ThwMaxBlock || waserror()) + if(nsrc < 4 || nsrc > ThwMaxBlock) return -1; - ut->src = src + 2; - ut->smax = src + nsrc; - /* * find the correct slot for this block, * the oldest block around. the encoder @@ -112,23 +104,30 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) } eblocks = b; if(cseq != seq){ - print("blocks not in decompression window: cseq=%d seq=%d cmask=%ux nb=%d\n", cseq, seq, cmask, eblocks - blocks); - error("unthwack bad window"); + print("blocks not in decompression window: cseq=%ld seq=%ld cmask=%lux nb=%ld\n", cseq, seq, cmask, eblocks - blocks); + return -1; } + smax = src + nsrc; + src += 2; utnbits = 0; utbits = 0; - while(ut->src < ut->smax || ut->nbits >= MinDecode){ - while(utnbits < 9){ - if(ut->src >= ut->smax) - error("unthwack eof"); + overbits = 0; + while(src < smax || utnbits - overbits >= MinDecode){ + while(utnbits < MaxOffDecode + BigLenBits){ utbits <<= 8; - utbits |= *ut->src++; + if(src < smax) + utbits |= *src++; + else + overbits += 8; utnbits += 8; } utnbits -= 9; off = (utbits >> utnbits) & ((1 << 9) - 1); + /* + * literal + */ bits = off >> 5; if(bits >= MaxOff){ *d++ = off; @@ -143,41 +142,46 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) bits += OffBase - 5; off <<= bits; - while(utnbits < bits){ - if(ut->src >= ut->smax) - error("unthwack eof"); - utbits <<= 8; - utbits |= *ut->src++; - utnbits += 8; - } utnbits -= bits; off |= (utbits >> utnbits) & ((1 << bits) - 1); off++; - len = 0; bits = 0; + utbits &= (1 << utnbits) - 1; do{ - len <<= 1; - if(utnbits < 1){ - if(ut->src >= ut->smax) - error("unthwack eof"); + bits++; + len = utbits >> (utnbits - bits); + }while(bits < BigLenBits && len > lentab.maxcode[bits]); + utnbits -= bits; + + if(bits < BigLenBits) + len = lentab.decode[lentab.last[bits] - len]; + else{ + while(utnbits < MaxLenDecode){ utbits <<= 8; - utbits |= *ut->src++; + if(src < smax) + utbits |= *src++; + else + overbits += 8; utnbits += 8; } - utnbits--; - len |= (utbits >> utnbits) & 1; - bits++; - }while(len > lentab.maxcode[bits]); - len = lentab.decode[lentab.last[bits] - len]; - - if(len == MaxLen - 1){ - ut->nbits = utnbits; - ut->bits = utbits; - len += iomegaget(ut) - 1; - utnbits = ut->nbits; - utbits = ut->bits; + + code = len - BigLenCode; + len = MaxFastLen; + bits = 8; + use = BigLenBase; + while(code >= use){ + len += use; + code -= use; + code <<= 1; + utnbits--; + code |= (utbits >> utnbits) & 1; + use <<= bits & 1; + bits++; + } + len += code; } + len += MinMatch; b = blocks; @@ -185,17 +189,19 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) off -= b->maxoff; b++; if(b >= eblocks) - error("unthwack offset"); + return -1; } if(d + len > dmax || b != blocks && len > off) - error("unthwack len"); + return -1; s = b->data + b->maxoff - off; es = s + len; while(s < es) *d++ = *s++; blocks->maxoff += len; } + if(utnbits < overbits) + return -1; len = d - blocks->data; memmove(dst, blocks->data, len); @@ -205,49 +211,5 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq) if(ut->slot >= DWinBlocks) ut->slot = 0; - poperror(); return len; } - -/* - * elias's omega code, modified - * for at least 3 bit transmission - */ -static ulong -iomegaget(Unthwack *ut) -{ - ulong v; - int b; - - v = bitget(ut, 3); - if((v & 0x4) == 0) - return v + 1; - for(;;){ - b = bitget(ut, 1); - if(b == 0) - return v + 1; - if(v > 16) - break; - v--; - v = (b << v) | bitget(ut, v); - } - error("unthwack iomegaget"); - return ~0; -} - -static ulong -bitget(Unthwack *ut, int nb) -{ - int c; - - while(ut->nbits < nb){ - if(ut->src >= ut->smax) - error("unthwack eof"); - c = *ut->src++; - ut->bits <<= 8; - ut->bits |= c; - ut->nbits += 8; - } - ut->nbits -= nb; - return (ut->bits >> ut->nbits) & ((1 << nb) - 1); -}