From ad8a1de3448aaf3172e0d64565c77904177cd885 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 12 Apr 1994 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1994-04-12 --- carrera/screen.c | 32 ++- pc/devvga.c | 711 +++++++++++++++++++++-------------------------- pc/l.s | 118 +------- port/devmouse.c | 41 ++- port/portfns.h | 4 - 5 files changed, 377 insertions(+), 529 deletions(-) diff --git a/carrera/screen.c b/carrera/screen.c index f40afa6771eb3d23b09676c3d7d47a2232f78ed8..dbe6439d8f3ddcac4ea5928b639a9f16925c9758 100644 --- a/carrera/screen.c +++ b/carrera/screen.c @@ -503,11 +503,13 @@ extern cursorunlock(void); * gscreen.ldepth is known to be >= 3 */ void -screenload(Rectangle r, uchar *data, int tl, int l) +screenload(Rectangle r, uchar *data, int tl, int l, int dolock) { uchar *q; int y; + USED(dolock); + if(!rectclip(&r, gscreen.r) || tl<=0) return; @@ -520,3 +522,31 @@ screenload(Rectangle r, uchar *data, int tl, int l) } unlock(&screenlock); } + +/* + * get a tile from screen memory. + * tile is at location r, first pixel in *data. + * tl is length of scan line to insert, + * l is amount to advance data after each scan line. + * gscreen.ldepth is known to be >= 3 + */ +void +screenunload(Rectangle r, uchar *data, int tl, int l, int dolock) +{ + uchar *q; + int y; + + USED(dolock); + + if(!rectclip(&r, gscreen.r) || tl<=0) + return; + + lock(&screenlock); + q = gbaddr(&gscreen, r.min); + for(y=r.min.y; ybits->base; for(i = defont->bits->width*Dy(defont->bits->r); i > 0; i--, l++) *l = (*l<<24) | ((*l>>8)&0x0000ff00) | ((*l<<8)&0x00ff0000) | (*l>>24); + /* * start in CGA mode */ @@ -407,60 +405,69 @@ screeninit(void) memset(CGASCREEN, 0, CGAWIDTH*CGAHEIGHT); } +static void +setmode(VGAmode *v) +{ + int i; + + /* turn screen off (to avoid damage) */ + srout(1, 0x21); + + for(i = 0; i < sizeof(v->general); i++) + genout(i, v->general[i]); + + for(i = 0; i < sizeof(v->sequencer); i++) + if(i == 1) + srout(i, v->sequencer[i]|0x20); /* avoid enabling screen */ + else + srout(i, v->sequencer[i]); + + crout(Cvre, 0); /* allow writes to CRT registers 0-7 */ + for(i = 0; i < sizeof(v->crt); i++) + crout(i, v->crt[i]); + + for(i = 0; i < sizeof(v->graphics); i++) + grout(i, v->graphics[i]); + + for(i = 0; i < sizeof(v->attribute); i++) + arout(i, v->attribute[i]); + + /* turn screen on */ + srout(1, v->sequencer[1]); +} + /* * reconfigure screen shape */ static void setscreen(int maxx, int maxy, int ldepth) { - int len, vgamaxy, width, i, x, s; - ulong *p, *oldp; + int i, x; - if(ldepth == 3) - setmode(&mode13); - else + switch(ldepth){ + case 0: setmode(&mode12); - - /* allocate a new soft bitmap area */ - width = (maxx*(1< (64*1024)/(vgascreen.width*BY2WD)) - vgamaxy = (64*1024)/(vgascreen.width*BY2WD); - else - vgamaxy = maxy; - vgascreen.base = (void*)SCREENMEM; - vgascreen.r.min = Pt(0, 0); - vgascreen.r.max = Pt(maxx, vgamaxy); - vgascreen.clipr = vgascreen.r; + break; + case 3: + setmode(&mode13); + break; + default: + error(Ebadarg); + } /* - * setup new soft screen, free memory for old screen + * setup a bitmap for the new size */ - oldp = gscreen.base; - s = splhi(); gscreen.ldepth = ldepth; - gscreen.width = width; + gscreen.width = (maxx*(1<setpage(i>>Footshift); + memset(gscreen.base, 0, Footprint); + } /* * default color map @@ -481,12 +488,6 @@ setscreen(int maxx, int maxy, int ldepth) } cga = 0; - /* - * display white window - */ - mbb = gscreen.r; - screenupdate(); - /* * set up inset system window */ @@ -494,42 +495,106 @@ setscreen(int maxx, int maxy, int ldepth) w = defont0.info[' '].width; window.min = Pt(50, 50); - window.max = add(window.min, Pt(10+w*64, 10+h*24)); + window.max = add(window.min, Pt(10+w*64, Footprint/(BY2WD*gscreen.width))); + vgacard->setpage(0); gbitblt(&gscreen, window.min, &gscreen, window, Zero); window = inset(window, 5); cursor = window.min; window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; hwcurs = 0; +} - mbb = gscreen.r; - screenupdate(); +/* + * Load a byte into screen memory. Assume that if the page + * is wrong we just need to increment it. + */ +static int +byteload(uchar *q, uchar *data, int m, int *page, uchar *e) +{ + int pg; + int diff; + + diff = 0; + if(q >= e){ + pg = ++*page; + vgacard->setpage(pg); + q -= Footprint; + diff -= Footprint; + } + *q ^= (*data^*q) & m; + return diff; } /* - * paste tile into soft screen. + * Load adjacent bytes into a screen memory. Assume that if the page + * is wrong we just need to increment it. + */ +static int +lineload(uchar *q, uchar *data, int len, int *page, uchar *e) +{ + int rem, pg; + int diff; + + diff = 0; + if(q >= e){ + pg = ++*page; + vgacard->setpage(pg); + q -= Footprint; + diff -= Footprint; + } + + rem = e - q; + + if(rem < len){ + memmove(q, data, rem); + pg = ++*page; + vgacard->setpage(pg); + q -= Footprint; + diff -= Footprint; + memmove(q+rem, data+rem, len-rem); + } else + memmove(q, data, len); + + return diff; +} + +/* + * paste tile into hard screen. * tile is at location r, first pixel in *data. tl is length of scan line to insert, * l is amount to advance data after each scan line. */ void -screenload(Rectangle r, uchar *data, int tl, int l) +screenload(Rectangle r, uchar *data, int tl, int l, int dolock) { - int y, lpart, rpart, mx, m, mr; - uchar *q; + int y, lpart, rpart, mx, m, mr, page, sw; + ulong off; + uchar *q, *e; extern void cursorlock(Rectangle); extern void cursorunlock(void); if(!rectclip(&r, gscreen.r) || tl<=0) return; + + if(dolock) + cursorlock(r); lock(&screenlock); - cursorlock(r); - screenupdate(); + q = gbaddr(&gscreen, r.min); mx = 7>>gscreen.ldepth; lpart = (r.min.x & mx) << gscreen.ldepth; rpart = (r.max.x & mx) << gscreen.ldepth; m = 0xFF >> lpart; mr = 0xFF ^ (0xFF >> rpart); + + off = q - (uchar*)gscreen.base; + page = off>>Footshift; + vgacard->setpage(page); + q = ((uchar*)gscreen.base) + (off&(Footprint-1)); + + sw = gscreen.width*sizeof(ulong); + e = ((uchar*)gscreen.base) + Footprint; + /* may need to do bit insertion on edges */ if(tl <= 0){ ; @@ -537,139 +602,228 @@ screenload(Rectangle r, uchar *data, int tl, int l) if(rpart) m &= mr; for(y=r.min.y; y 2) - memmove(q+1, data+1, tl-2); - q[tl-1] ^= (data[tl-1]^q[tl-1]) & mr; - q += gscreen.width*sizeof(ulong); + if(q + tl <= e){ + *q ^= (*data^*q) & m; + if(tl > 2) + memmove(q+1, data+1, tl-2); + q[tl-1] ^= (data[tl-1]^q[tl-1]) & mr; + } else { /* new page */ + q += byteload(q, data, m, &page, e); + if(tl > 2) + q += lineload(q+1, data+1, tl-2, &page, e); + q += byteload(q+tl-1, data+tl-1, mr, &page, e); + } + q += sw; data += l; } - mbbrect(r); - screenupdate(); - cursorunlock(); - screenupdate(); + unlock(&screenlock); + if(dolock) + cursorunlock(); } /* - * copy little endian soft screen to big endian hard screen + * Get a byte from screen memory. Assume that if the page + * is wrong we just need to increment it. */ -void -screenupdate(void) +static int +byteunload(uchar *q, uchar *data, int m, int *page, uchar *e) { - uchar *sp, *hp, *edisp; - int y, len, incs, inch, off, page; - Rectangle r; - void* (*f)(void*, void*, long); + int pg; + int diff; + + diff = 0; + if(q >= e){ + pg = ++*page; + vgacard->setpage(pg); + q -= Footprint; + diff -= Footprint; + } + *data ^= (*q^*data) & m; + return diff; +} - r = mbb; - mbb = NULLMBB; +/* + * Get a vector of bytes from screen memory. Assume that if the page + * is wrong we just need to increment it. + */ +static int +lineunload(uchar *q, uchar *data, int len, int *page, uchar *e) +{ + int rem, pg; + int diff; + + diff = 0; + if(q >= e){ + pg = ++*page; + vgacard->setpage(pg); + q -= Footprint; + diff -= Footprint; + } - if(Dy(r) < 0) - return; + rem = e - q; - if(r.min.x < 0) - r.min.x = 0; - if(r.min.y < 0) - r.min.y = 0; - if(r.max.x > gscreen.r.max.x) - r.max.x = gscreen.r.max.x; - if(r.max.y > gscreen.r.max.y) - r.max.y = gscreen.r.max.y; + if(rem < len){ + memmove(data, q, rem); + pg = ++*page; + vgacard->setpage(pg); + q -= Footprint; + diff -= Footprint; + memmove(data+rem, q+rem, len-rem); + } else + memmove(data, q, len); - incs = gscreen.width * BY2WD; - inch = vgascreen.width * BY2WD; + return diff; +} - switch(gscreen.ldepth){ - case 0: - r.min.x &= ~15; /* 16 pixel alignment for l0update() */ - f = memmove; - len = (r.max.x + 7)/8 - r.min.x/8; - if(len & 1) - len++; /* 16 bit alignment for l0update() */ - break; - case 1: - r.min.x &= ~15; /* 8 pixel alignment for l1update() */ - f = l1update; - len = (r.max.x + 7)/8 - r.min.x/8; - if(len & 1) - len++; /* 8 pixel alignment for l1update() */ - break; - case 2: - r.min.x &= ~7; /* 8 pixel alignment for l2update() */ - f = l2update; - len = (r.max.x + 7)/8 - r.min.x/8; - break; - case 3: - f = memmove; - r.min.x &= ~3; - r.max.x = ROUND(r.max.x, 4); - len = r.max.x - r.min.x; - break; - default: - return; - } - if(len < 1) +/* + * paste tile into hard screen. + * tile is at location r, first pixel in *data. tl is length of scan line to insert, + * l is amount to advance data after each scan line. + */ +void +screenunload(Rectangle r, uchar *data, int tl, int l, int dolock) +{ + int y, lpart, rpart, mx, m, mr, page, sw; + ulong off; + uchar *q, *e; + extern void cursorlock(Rectangle); + extern void cursorunlock(void); + + if(!rectclip(&r, gscreen.r) || tl<=0) return; - off = r.min.y * vgascreen.width * BY2WD + (r.min.x>>(3 - vgascreen.ldepth)); - page = off>>16; - off &= (1<<16)-1; - hp = ((uchar*)vgascreen.base) + off; - off = r.min.y * gscreen.width * BY2WD - + (r.min.x>>(3 - gscreen.ldepth)); - sp = ((uchar*)gscreen.base) + off; + if(dolock) + cursorlock(r); + lock(&screenlock); - edisp = ((uchar*)vgascreen.base) + 64*1024; + q = gbaddr(&gscreen, r.min); + mx = 7>>gscreen.ldepth; + lpart = (r.min.x & mx) << gscreen.ldepth; + rpart = (r.max.x & mx) << gscreen.ldepth; + m = 0xFF >> lpart; + mr = 0xFF ^ (0xFF >> rpart); + + off = q - (uchar*)gscreen.base; + page = off>>Footshift; vgacard->setpage(page); - for(y = r.min.y; y < r.max.y; y++){ - if(hp + inch < edisp){ - f(hp, sp, len); - sp += incs; - hp += inch; - } else { - off = edisp - hp; - if(off <= len){ - if(off > 0) - f(hp, sp, off); - vgacard->setpage(++page); - if(len - off > 0) - f(vgascreen.base, sp+off, len - off); + q = ((uchar*)gscreen.base) + (off&(Footprint-1)); + + sw = gscreen.width*sizeof(ulong); + e = ((uchar*)gscreen.base) + Footprint; + + /* may need to do bit insertion on edges */ + if(tl <= 0){ + ; + }else if(tl == 1){ /* all in one byte */ + if(rpart) + m &= mr; + for(y=r.min.y; ysetpage(++page); + q += byteunload(q, data, m, &page, e); + q += lineunload(q+1, data+1, tl-1, &page, e); } - sp += incs; - hp += inch - 64*1024; + q += sw; + data += l; } - } + }else if(lpart == 0){ + for(y=r.min.y; y 2) + memmove(data+1, q+1, tl-2); + data[tl-1] ^= (q[tl-1]^data[tl-1]) & mr; + } else { /* new page */ + q += byteunload(q, data, m, &page, e); + if(tl > 2) + q += lineunload(q+1, data+1, tl-2, &page, e); + q += byteunload(q+tl-1, data+tl-1, mr, &page, e); + } + q += sw; + data += l; + } + + unlock(&screenlock); + if(dolock) + cursorunlock(); } +/* + * write a string to the screen + */ void screenputs(char *s, int n) { @@ -702,12 +856,7 @@ screenputs(char *s, int n) s += i; screenputc(buf); } - if(isscroll) { - mbb = window; - isscroll = 0; - } - screenupdate(); unlock(&screenlock); } @@ -760,91 +909,6 @@ crout(int reg, int val) outb(CR, val); } -static void -setmode(VGAmode *v) -{ - int i; - - /* turn screen off (to avoid damage) */ - srout(1, 0x21); - - for(i = 0; i < sizeof(v->general); i++) - genout(i, v->general[i]); - - for(i = 0; i < sizeof(v->sequencer); i++) - if(i == 1) - srout(i, v->sequencer[i]|0x20); /* avoid enabling screen */ - else - srout(i, v->sequencer[i]); - - crout(Cvre, 0); /* allow writes to CRT registers 0-7 */ - for(i = 0; i < sizeof(v->crt); i++) - crout(i, v->crt[i]); - - for(i = 0; i < sizeof(v->graphics); i++) - grout(i, v->graphics[i]); - - for(i = 0; i < sizeof(v->attribute); i++) - arout(i, v->attribute[i]); - - /* turn screen on */ - srout(1, v->sequencer[1]); -} - -static void -getmode(VGAmode *v) -{ - int i; - v->general[0] = inb(0x3cc); - v->general[1] = inb(0x3ca); - for(i = 0; i < sizeof(v->sequencer); i++) { - outb(SRX, i); - v->sequencer[i] = inb(SR); - } - for(i = 0; i < sizeof(v->crt); i++) { - outb(CRX, i); - v->crt[i] = inb(CR); - } - for(i = 0; i < sizeof(v->graphics); i++) { - outb(GRX, i); - v->graphics[i] = inb(GR); - } - for(i = 0; i < sizeof(v->attribute); i++) { - inb(0x3DA); - outb(ARW, i | 0x20); - v->attribute[i] = inb(ARR); - } -} - -static void -printmode(VGAmode *v) -{ - int i; - print("g %2.2x %2x\n", - v->general[0], v->general[1]); - - print("s "); - for(i = 0; i < sizeof(v->sequencer); i++) { - print(" %2.2x", v->sequencer[i]); - } - - print("\nc "); - for(i = 0; i < sizeof(v->crt); i++) { - print(" %2.2x", v->crt[i]); - } - - print("\ng "); - for(i = 0; i < sizeof(v->graphics); i++) { - print(" %2.2x", v->graphics[i]); - } - - print("\na "); - for(i = 0; i < sizeof(v->attribute); i++) { - print(" %2.2x", v->attribute[i]); - } - print("\n"); -} - /* * expand 3 and 6 bits of color to 32 */ @@ -883,35 +947,6 @@ hwcursmove(int x, int y) USED(x, y); } -/* - * collect changes to the 'soft' screen - */ -void -mbbrect(Rectangle r) -{ - if (r.min.x < mbb.min.x) - mbb.min.x = r.min.x; - if (r.min.y < mbb.min.y) - mbb.min.y = r.min.y; - if (r.max.x > mbb.max.x) - mbb.max.x = r.max.x; - if (r.max.y > mbb.max.y) - mbb.max.y = r.max.y; -} - -void -mbbpt(Point p) -{ - if (p.x < mbb.min.x) - mbb.min.x = p.x; - if (p.y < mbb.min.y) - mbb.min.y = p.y; - if (p.x >= mbb.max.x) - mbb.max.x = p.x+1; - if (p.y >= mbb.max.y) - mbb.max.y = p.y+1; -} - /* * paging routines for different cards */ @@ -975,7 +1010,7 @@ s3page(int page) /* * I don't understand why these are different. */ - if(vgascreen.ldepth == 3){ + if(gscreen.ldepth == 3){ /* * The S3 registers need to be unlocked for this. * Let's hope they are already: @@ -994,16 +1029,6 @@ s3page(int page) crout(0x35, (page<<2) & 0x0C); } -void -mousescreenupdate(void) -{ - if(canlock(&screenlock) == 0) - return; - - screenupdate(); - unlock(&screenlock); -} - static void cgascreenputc(int c) { @@ -1047,13 +1072,12 @@ scroll(void) int o; Rectangle r; - o = 5*h; - r = Rpt(Pt(window.min.x, window.min.y+o), window.max); + vgacard->setpage(0); + r = Rpt(Pt(window.min.x, window.max.y+h), window.max); gbitblt(&gscreen, window.min, &gscreen, r, S); r = Rpt(Pt(window.min.x, window.max.y-o), window.max); gbitblt(&gscreen, r.min, &gscreen, r, Zero); cursor.y -= o; - isscroll = 1; } static void @@ -1061,7 +1085,6 @@ screenputc(char *buf) { int pos; - mbbpt(cursor); switch(buf[0]) { case '\n': if(cursor.y+h >= window.max.y) @@ -1087,7 +1110,6 @@ screenputc(char *buf) cursor = gsubfstring(&gscreen, cursor, &defont0, buf, S); } - mbbpt(Pt(cursor.x, cursor.y+h)); } int @@ -1144,104 +1166,3 @@ setcolor(ulong p, ulong r, ulong g, ulong b) unlock(&screenlock); return ~0; } - -/* - * Table for separating bits in a ldepth 1 bitmap. - * This aids in coverting a big-endian ldepth 1 bitmap into the - * 2 big-endian ldepth 0 bitmaps used for the VGA bit planes. - * - * if the bits in uchar x are labeled - * 76543210 - * then l1septab[x] yields a ulong with bits - * ________7531________6420 - * where _ represents a bit whose value is 0. - * - * This table is used by l1update() in l.s. l1update is implemented - * in assembler for speed. - * - */ -ulong l1septab[] = { - 0x00000, 0x00001, 0x10000, 0x10001, 0x00002, 0x00003, 0x10002, 0x10003, - 0x20000, 0x20001, 0x30000, 0x30001, 0x20002, 0x20003, 0x30002, 0x30003, - 0x00004, 0x00005, 0x10004, 0x10005, 0x00006, 0x00007, 0x10006, 0x10007, - 0x20004, 0x20005, 0x30004, 0x30005, 0x20006, 0x20007, 0x30006, 0x30007, - 0x40000, 0x40001, 0x50000, 0x50001, 0x40002, 0x40003, 0x50002, 0x50003, - 0x60000, 0x60001, 0x70000, 0x70001, 0x60002, 0x60003, 0x70002, 0x70003, - 0x40004, 0x40005, 0x50004, 0x50005, 0x40006, 0x40007, 0x50006, 0x50007, - 0x60004, 0x60005, 0x70004, 0x70005, 0x60006, 0x60007, 0x70006, 0x70007, - 0x00008, 0x00009, 0x10008, 0x10009, 0x0000a, 0x0000b, 0x1000a, 0x1000b, - 0x20008, 0x20009, 0x30008, 0x30009, 0x2000a, 0x2000b, 0x3000a, 0x3000b, - 0x0000c, 0x0000d, 0x1000c, 0x1000d, 0x0000e, 0x0000f, 0x1000e, 0x1000f, - 0x2000c, 0x2000d, 0x3000c, 0x3000d, 0x2000e, 0x2000f, 0x3000e, 0x3000f, - 0x40008, 0x40009, 0x50008, 0x50009, 0x4000a, 0x4000b, 0x5000a, 0x5000b, - 0x60008, 0x60009, 0x70008, 0x70009, 0x6000a, 0x6000b, 0x7000a, 0x7000b, - 0x4000c, 0x4000d, 0x5000c, 0x5000d, 0x4000e, 0x4000f, 0x5000e, 0x5000f, - 0x6000c, 0x6000d, 0x7000c, 0x7000d, 0x6000e, 0x6000f, 0x7000e, 0x7000f, - 0x80000, 0x80001, 0x90000, 0x90001, 0x80002, 0x80003, 0x90002, 0x90003, - 0xa0000, 0xa0001, 0xb0000, 0xb0001, 0xa0002, 0xa0003, 0xb0002, 0xb0003, - 0x80004, 0x80005, 0x90004, 0x90005, 0x80006, 0x80007, 0x90006, 0x90007, - 0xa0004, 0xa0005, 0xb0004, 0xb0005, 0xa0006, 0xa0007, 0xb0006, 0xb0007, - 0xc0000, 0xc0001, 0xd0000, 0xd0001, 0xc0002, 0xc0003, 0xd0002, 0xd0003, - 0xe0000, 0xe0001, 0xf0000, 0xf0001, 0xe0002, 0xe0003, 0xf0002, 0xf0003, - 0xc0004, 0xc0005, 0xd0004, 0xd0005, 0xc0006, 0xc0007, 0xd0006, 0xd0007, - 0xe0004, 0xe0005, 0xf0004, 0xf0005, 0xe0006, 0xe0007, 0xf0006, 0xf0007, - 0x80008, 0x80009, 0x90008, 0x90009, 0x8000a, 0x8000b, 0x9000a, 0x9000b, - 0xa0008, 0xa0009, 0xb0008, 0xb0009, 0xa000a, 0xa000b, 0xb000a, 0xb000b, - 0x8000c, 0x8000d, 0x9000c, 0x9000d, 0x8000e, 0x8000f, 0x9000e, 0x9000f, - 0xa000c, 0xa000d, 0xb000c, 0xb000d, 0xa000e, 0xa000f, 0xb000e, 0xb000f, - 0xc0008, 0xc0009, 0xd0008, 0xd0009, 0xc000a, 0xc000b, 0xd000a, 0xd000b, - 0xe0008, 0xe0009, 0xf0008, 0xf0009, 0xe000a, 0xe000b, 0xf000a, 0xf000b, - 0xc000c, 0xc000d, 0xd000c, 0xd000d, 0xc000e, 0xc000f, 0xd000e, 0xd000f, - 0xe000c, 0xe000d, 0xf000c, 0xf000d, 0xe000e, 0xe000f, 0xf000e, 0xf000f, -}; - -/* - * Table for separating and reversing bits in a ldepth 2 bitmap. - * This aids in coverting a little endian ldepth 1 bitmap into the - * 4 big-endian ldepth 0 bitmaps used for the VGA bit planes. - * - * if the bits in uchar x are labeled - * 76543210 - * then l1septab[x] yields a ulongt with bits - * ______73______62______51______40 - * where _ represents a bit whose value is 0. - * - * This table is used by l2update() in l.s. l2update is implemented - * in assembler for speed. - * - */ -ulong l2septab[] = { - 0x0000000, 0x0000001, 0x0000100, 0x0000101, 0x0010000, 0x0010001, 0x0010100, 0x0010101, - 0x1000000, 0x1000001, 0x1000100, 0x1000101, 0x1010000, 0x1010001, 0x1010100, 0x1010101, - 0x0000002, 0x0000003, 0x0000102, 0x0000103, 0x0010002, 0x0010003, 0x0010102, 0x0010103, - 0x1000002, 0x1000003, 0x1000102, 0x1000103, 0x1010002, 0x1010003, 0x1010102, 0x1010103, - 0x0000200, 0x0000201, 0x0000300, 0x0000301, 0x0010200, 0x0010201, 0x0010300, 0x0010301, - 0x1000200, 0x1000201, 0x1000300, 0x1000301, 0x1010200, 0x1010201, 0x1010300, 0x1010301, - 0x0000202, 0x0000203, 0x0000302, 0x0000303, 0x0010202, 0x0010203, 0x0010302, 0x0010303, - 0x1000202, 0x1000203, 0x1000302, 0x1000303, 0x1010202, 0x1010203, 0x1010302, 0x1010303, - 0x0020000, 0x0020001, 0x0020100, 0x0020101, 0x0030000, 0x0030001, 0x0030100, 0x0030101, - 0x1020000, 0x1020001, 0x1020100, 0x1020101, 0x1030000, 0x1030001, 0x1030100, 0x1030101, - 0x0020002, 0x0020003, 0x0020102, 0x0020103, 0x0030002, 0x0030003, 0x0030102, 0x0030103, - 0x1020002, 0x1020003, 0x1020102, 0x1020103, 0x1030002, 0x1030003, 0x1030102, 0x1030103, - 0x0020200, 0x0020201, 0x0020300, 0x0020301, 0x0030200, 0x0030201, 0x0030300, 0x0030301, - 0x1020200, 0x1020201, 0x1020300, 0x1020301, 0x1030200, 0x1030201, 0x1030300, 0x1030301, - 0x0020202, 0x0020203, 0x0020302, 0x0020303, 0x0030202, 0x0030203, 0x0030302, 0x0030303, - 0x1020202, 0x1020203, 0x1020302, 0x1020303, 0x1030202, 0x1030203, 0x1030302, 0x1030303, - 0x2000000, 0x2000001, 0x2000100, 0x2000101, 0x2010000, 0x2010001, 0x2010100, 0x2010101, - 0x3000000, 0x3000001, 0x3000100, 0x3000101, 0x3010000, 0x3010001, 0x3010100, 0x3010101, - 0x2000002, 0x2000003, 0x2000102, 0x2000103, 0x2010002, 0x2010003, 0x2010102, 0x2010103, - 0x3000002, 0x3000003, 0x3000102, 0x3000103, 0x3010002, 0x3010003, 0x3010102, 0x3010103, - 0x2000200, 0x2000201, 0x2000300, 0x2000301, 0x2010200, 0x2010201, 0x2010300, 0x2010301, - 0x3000200, 0x3000201, 0x3000300, 0x3000301, 0x3010200, 0x3010201, 0x3010300, 0x3010301, - 0x2000202, 0x2000203, 0x2000302, 0x2000303, 0x2010202, 0x2010203, 0x2010302, 0x2010303, - 0x3000202, 0x3000203, 0x3000302, 0x3000303, 0x3010202, 0x3010203, 0x3010302, 0x3010303, - 0x2020000, 0x2020001, 0x2020100, 0x2020101, 0x2030000, 0x2030001, 0x2030100, 0x2030101, - 0x3020000, 0x3020001, 0x3020100, 0x3020101, 0x3030000, 0x3030001, 0x3030100, 0x3030101, - 0x2020002, 0x2020003, 0x2020102, 0x2020103, 0x2030002, 0x2030003, 0x2030102, 0x2030103, - 0x3020002, 0x3020003, 0x3020102, 0x3020103, 0x3030002, 0x3030003, 0x3030102, 0x3030103, - 0x2020200, 0x2020201, 0x2020300, 0x2020301, 0x2030200, 0x2030201, 0x2030300, 0x2030301, - 0x3020200, 0x3020201, 0x3020300, 0x3020301, 0x3030200, 0x3030201, 0x3030300, 0x3030301, - 0x2020202, 0x2020203, 0x2020302, 0x2020303, 0x2030202, 0x2030203, 0x2030302, 0x2030303, - 0x3020202, 0x3020203, 0x3020302, 0x3020303, 0x3030202, 0x3030203, 0x3030302, 0x3030303, -}; - diff --git a/pc/l.s b/pc/l.s index 4d59232201ec9257eb47301e78cbf7cfa8f0fa3d..220332ad188207f99fb8146e0a63e4d750424321 100644 --- a/pc/l.s +++ b/pc/l.s @@ -585,7 +585,7 @@ TEXT x86(SB),$0 JZ is486 MOVL $586,AX JMP done -is486 +is486: MOVL $486,AX JMP done is386: @@ -646,122 +646,6 @@ TEXT config(SB),$0 #define SR 0x3C5 /* sequence registers */ #define Smmask 0x02 /* map mask */ -/* - * invert the ldepth 0 bitmap - */ -TEXT l0update(SB),$0 - MOVL from+4(FP),SI - MOVL to+0(FP),DI - MOVL len+8(FP),BX - - MOVL BX,CX - SHRL $2,CX - JZ l01 -l00: - MOVL -4(SI)(CX*4),AX - NOTL AX - MOVL AX,-4(DI)(CX*4) - LOOP l00 -l01: - MOVL BX,CX - ANDL $(~3),BX - ANDL $3,CX - JZ l03 - ADDL BX,SI - ADDL BX,DI -l02: - MOVB -1(SI)(CX*1),AL - NOTL AX - MOVB AL,-1(DI)(CX*1) - LOOP l02 -l03: - RET - -/* - * separate ldepth 1 bitmap into 2 bit planes - */ -TEXT l1update(SB),$0 - XORL AX,AX - MOVL from+4(FP),SI - MOVL to+0(FP),DI - MOVL len+8(FP),CX - MOVB $(Smmask),AL - MOVW $(SRX),DX - OUTB -l10: - MOVL -4(SI)(CX*2),DX - MOVB DL,AL - MOVL l1septab(SB)(AX*4),BX - SHLL $4,BX - RORL $8,DX - MOVB DL,AL - ORL l1septab(SB)(AX*4),BX - RORL $12,BX - RORL $8,DX - MOVB DL,AL - ORL l1septab(SB)(AX*4),BX - SHLL $4,BX - RORL $8,DX - MOVB DL,AL - ORL l1septab(SB)(AX*4),BX - ROLL $8,BX - MOVW $(SR),DX - MOVB $0x5,AL /* write lo order bits to bit planes 1 & 3 */ - OUTB - MOVW BX,-2(DI)(CX*1) - SHRL $16,BX /* write hi order bits to bit planes 0 & 2 */ - MOVB $0xA,AL - OUTB - MOVW BX,-2(DI)(CX*1) - LOOP l10 - RET - -/* - * separate ldepth 2 bitmap into 4 bit planes - */ -TEXT l2update(SB),$0 - XORL AX,AX - MOVL from+4(FP),SI - MOVL to+0(FP),DI - MOVL len+8(FP),CX - MOVB $(Smmask),AL - MOVW $(SRX),DX - OUTB -l20: - MOVL -4(SI)(CX*4),DX - MOVB DL,AL - MOVL l2septab(SB)(AX*4),BX - SHLL $2,BX - SHRL $8,DX - MOVB DL,AL - ORL l2septab(SB)(AX*4),BX - SHLL $2,BX - SHRL $8,DX - MOVB DL,AL - ORL l2septab(SB)(AX*4),BX - SHLL $2,BX - SHRL $8,DX - MOVB DL,AL - ORL l2septab(SB)(AX*4),BX - MOVW $(SR),DX - MOVB $0x1,AL /* plane 3 */ - OUTB - MOVB BX,-1(DI)(CX*1) - MOVB $0x2,AL /* plane 2 */ - OUTB - SHRL $8,BX - MOVB BX,-1(DI)(CX*1) - MOVB $0x4,AL /* plane 1 */ - OUTB - SHRL $8,BX - MOVB BX,-1(DI)(CX*1) - MOVB $0x8,AL /* plane 0*/ - OUTB - SHRL $8,BX - MOVB BX,-1(DI)(CX*1) - LOOP l20 - RET - /* * The DP8390 ethernet chip needs some time between * successive chip selects, so we force a jump into diff --git a/port/devmouse.c b/port/devmouse.c index 2dd1358527575b57fae6dafeed871e8ac137526b..98cb514defee7915939ecb970ce24d3a1570e9d3 100644 --- a/port/devmouse.c +++ b/port/devmouse.c @@ -115,9 +115,23 @@ GBitmap cursorback = {0, 0, 16, 16} }; +ulong cursorworkbits[16*4]; +GBitmap cursorwork = +{ + cursorworkbits, + 0, + 1, + 0, + {0, 0, 16, 16}, + {0, 0, 16, 16} +}; + void Cursortocursor(Cursor*); int mousechanged(void*); +extern void screenload(Rectangle, uchar*, int, int, int); +extern void screenunload(Rectangle, uchar*, int, int, int); + enum{ Qdir, Qcursor, @@ -156,11 +170,14 @@ mouseinit(void) { if(!conf.monitor) return; - if(gscreen.ldepth > 3) + if(gscreen.ldepth > 3){ cursorback.ldepth = 0; - else{ + cursorwork.ldepth = 0; + }else{ cursorback.ldepth = gscreen.ldepth; cursorback.width = ((16 << gscreen.ldepth) + 31) >> 5; + cursorwork.ldepth = gscreen.ldepth; + cursorwork.width = ((16 << gscreen.ldepth) + 31) >> 5; } cursoron(1); } @@ -434,12 +451,15 @@ cursoron(int dolock) cursor.r.min = mouse.xy; cursor.r.max = add(mouse.xy, Pt(16, 16)); cursor.r = raddp(cursor.r, cursor.offset); - gbitblt(&cursorback, Pt(0, 0), &gscreen, cursor.r, S); - gbitblt(&gscreen, cursor.r.min, + screenunload(cursor.r, (uchar*)cursorworkbits, + (16>>3) << gscreen.ldepth, cursorwork.width*BY2WD, 0); + memmove(cursorbackbits, cursorworkbits, 16*cursorback.width*BY2WD); + gbitblt(&cursorwork, cursorwork.r.min, &clr, Rect(0, 0, 16, 16), flipping? flipD[D&~S] : D&~S); - gbitblt(&gscreen, cursor.r.min, + gbitblt(&cursorwork, cursorwork.r.min, &set, Rect(0, 0, 16, 16), flipping? flipD[S|D] : S|D); - mbbrect(cursor.r); + screenload(cursor.r, (uchar*)cursorworkbits, + (16>>3) << gscreen.ldepth, cursorwork.width*BY2WD, 0); } } if(dolock) @@ -454,11 +474,9 @@ cursoroff(int dolock) if(dolock) lock(&cursor); if(--cursor.visible == 0) { - if(!hwcurs) { - gbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S); - mbbrect(cursor.r); - mousescreenupdate(); - } + if(!hwcurs) + screenload(cursor.r, (uchar*)cursorbackbits, + (16>>3) << gscreen.ldepth, cursorback.width*BY2WD, 0); } if(dolock) unlock(&cursor); @@ -480,7 +498,6 @@ mouseclock(void) mouse.redraw = 0; cursoroff(0); cursoron(0); - mousescreenupdate(); unlock(&cursor); } } diff --git a/port/portfns.h b/port/portfns.h index 0adf42e6705970bed43994c40a56116a04fb2cee..3827d8b39c446fd8243ac78d91d7a12ef0b33739 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -129,8 +129,6 @@ int m3mouseputc(int); void machinit(void); #define malloc(s) mallocz(s, 1) void* mallocz(ulong, int); -void mbbpt(Point); -void mbbrect(Rectangle); void mfreeseg(Segment*, ulong, int); void mmurelease(Proc*); void mmuswitch(Proc*); @@ -144,7 +142,6 @@ void mousebuttons(int); void mouseclock(void); void mousectl(char*); int mouseputc(int); -void mousescreenupdate(void); void mousetrack(int, int, int); int msize(void*); Chan* namec(char*, int, int, ulong); @@ -228,7 +225,6 @@ void sccsetup(void*, ulong, int); void sched(void); void schedinit(void); int screenbits(void); -void screenupdate(void); int scsiexec(Target*, int, uchar*, int, void*, int*); int scsiinv(int, int, Target**, uchar**, char*); Target* scsiunit(int, int);