From d6ed10b19a788b2cc9b2d7f52f539859e23926e0 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 9 Aug 1994 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1994-08-09 --- pc/clock.c | 51 +++++++++++++++++++++++++------------------ pc/devvga.c | 59 +++++++++++++++++++++++++------------------------- pc/vgas3.c | 33 ++++++++++++++++++++++++---- port/portfns.h | 1 + port/proc.c | 7 ++++++ 5 files changed, 97 insertions(+), 54 deletions(-) diff --git a/pc/clock.c b/pc/clock.c index a7fc8b33a8b7d559f6e6ea0821108a4d202f9e18..4b98cef60f0a3c38d7dbccb2c4bafc844abd57d9 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -27,7 +27,8 @@ enum Freq= 1193182, /* Real clock frequency */ }; -static int cpufreq = 66; +static int cpufreq = 66000000; +static int cpumhz = 66; static int cputype = 486; static int loopconst = 100; @@ -59,14 +60,16 @@ clock(Ureg *ur, void *arg) nrun = (nrdy+nrun)*1000; MACHP(0)->load = (MACHP(0)->load*19+nrun)/20; - if(up && (ur->cs&0xffff) == UESEL && up->state == Running){ + if(up && up->state == Running){ if(anyready()) sched(); /* user profiling clock */ - islow = 1; - spllo(); /* in case we fault */ - (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); + if((ur->cs&0xffff) == UESEL){ + islow = 1; + spllo(); /* in case we fault */ + (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); + } } /* @@ -96,7 +99,7 @@ delay(int l) void printcpufreq(void) { - print("CPU is a %ud MHz %d\n", cpufreq, cputype); + print("CPU is a %ud MHz (%ud Hz) %d\n", cpumhz, cpufreq, cputype); } void @@ -105,6 +108,21 @@ clockinit(void) ulong x, y; /* change in counter */ ulong cycles, loops; + switch(cputype = x86()){ + case 386: + loops = 10000; + cycles = 32; + break; + case 486: + loops = 10000; + cycles = 22; + break; + default: + loops = 30000; + cycles = 23; + break; + } + /* * set vector for clock interrupts */ @@ -117,6 +135,7 @@ clockinit(void) outb(T0cntr, (Freq/HZ)); /* low byte */ outb(T0cntr, (Freq/HZ)>>8); /* high byte */ + /* * measure time for the loop * @@ -129,7 +148,6 @@ clockinit(void) * prefetch buffer. * */ - loops = 10000; outb(Tmode, Latch0); x = inb(T0cntr); x |= inb(T0cntr)<<8; @@ -141,27 +159,18 @@ clockinit(void) /* * counter goes at twice the frequency, once per transition, - * i.e., twice per the square wave + * i.e., twice per square wave */ x >>= 1; /* * figure out clock frequency and a loop multiplier for delay(). */ - switch(cputype = x86()){ - case 386: - cycles = 32; - break; - case 486: - cycles = 22; - break; - default: - cycles = 24; - break; - } cpufreq = loops*((cycles*Freq)/x); loopconst = (cpufreq/1000)/cycles; /* AAM+LOOP's for 1 ms */ - /* convert to MHz */ - cpufreq = cpufreq/1000000; + /* + * add in possible .1% error and convert to MHz + */ + cpumhz = (cpufreq + cpufreq/1000)/1000000; } diff --git a/pc/devvga.c b/pc/devvga.c index 068a4b3f1f2038948a51040ae3a7ff423d25bfb1..bb568d6b9fe2551d39c0cb89279e5bed9d20dff4 100644 --- a/pc/devvga.c +++ b/pc/devvga.c @@ -825,20 +825,20 @@ screenload(Rectangle r, uchar *data, int tl, int l, int dolock) data += l; } }else for(y=r.min.y; y 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; + 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; + } unlock(&palettelock); if(dolock && hwgc == 0) @@ -900,9 +900,10 @@ lineunload(uchar *q, uchar *data, int len, int *page, uchar *e) } /* - * 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. + * 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. */ void screenunload(Rectangle r, uchar *data, int tl, int l, int dolock) @@ -981,20 +982,20 @@ screenunload(Rectangle r, uchar *data, int tl, int l, int dolock) data += l; } }else 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; + if(q + tl <= e){ + *data ^= (*q^*data) & m; + if(tl > 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(&palettelock); if(dolock && hwgc == 0) diff --git a/pc/vgas3.c b/pc/vgas3.c index b85e43f3bff21888fd3a0c6701cb457163a21273..5491a03478bcead6db57df780c16ff2f2d1be42b 100644 --- a/pc/vgas3.c +++ b/pc/vgas3.c @@ -17,6 +17,7 @@ static Lock s3pagelock; static ulong storage; static Point hotpoint; +static Cursor loaded; extern Bitmap gscreen; @@ -116,15 +117,28 @@ load(Cursor *c) int x, y; /* - * Disable the cursor and lock the display - * memory so we can update the cursor bitmap. + * Lock the display memory 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(&s3pagelock); + if(memcmp(c, &loaded, sizeof(Cursor)) == 0){ + vsyncactive(); + vgaxo(Crtx, 0x45, 0x01); + unlock(&s3pagelock); + return; + } + memmove(&loaded, c, sizeof(Cursor)); + + /* + * Disable the cursor. * Set the display page (do we need to restore * the current contents when done?) and the * pointer to the two planes. What if this crosses * into a new page? */ disable(); - lock(&s3pagelock); sets3page(storage>>16); p = ((uchar*)gscreen.base) + (storage & 0xFFFF); @@ -138,6 +152,9 @@ load(Cursor *c) * 1 0 background colour * 1 1 foreground colour * Put the cursor into the top-left of the 64x64 array. + * + * The cursor pattern in memory is interleaved words of + * AND and XOR patterns. */ for(y = 0; y < 64; y++){ for(x = 0; x < 64/8; x += 2){ @@ -155,7 +172,6 @@ load(Cursor *c) } } } - unlock(&s3pagelock); /* * Set the cursor hotpoint and enable the cursor. @@ -163,6 +179,8 @@ load(Cursor *c) hotpoint = c->offset; vsyncactive(); vgaxo(Crtx, 0x45, 0x01); + + unlock(&s3pagelock); } static int @@ -170,10 +188,16 @@ move(Point p) { int x, xo, y, yo; + if(canlock(&s3pagelock) == 0) + return -1; + /* * Mustn't position the cursor offscreen even partially, * or it disappears. Therefore, if x or y is -ve, adjust the * cursor offset instead. + * There seems to be a bug in that if the offset is 1, the + * cursor doesn't disappear off the left edge properly, so + * round it up to be even. */ if((x = p.x+hotpoint.x) < 0){ xo = -x; @@ -196,6 +220,7 @@ move(Point p) vgaxo(Crtx, 0x4F, yo); vgaxo(Crtx, 0x48, (y>>8) & 0x07); + unlock(&s3pagelock); return 0; } diff --git a/port/portfns.h b/port/portfns.h index 7560a5bf9e3a68dd3773641285db9e3aa8cd7c00..133ca8913f1677527c172cee7a3eaebf7fad5ac4 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -2,6 +2,7 @@ void addrootfile(char*, uchar*, ulong); void alarmkproc(void*); Block* allocb(int); int anyready(void); +int anyready0(void); Image* attachimage(int, Chan*, ulong, ulong); long authcheck(Chan*, char*, int); void authclose(Chan*); diff --git a/port/proc.c b/port/proc.c index e1bd3349f4e7231fc15d12f8947949b589337d26..575f09a6462ae351dd9cdcd36ee3aa3cd2773c97 100644 --- a/port/proc.c +++ b/port/proc.c @@ -111,6 +111,12 @@ anyready(void) return nrdy; } +int +anyready0(void) +{ + return runq->head != 0; +} + void ready(Proc *p) { @@ -734,6 +740,7 @@ procdump(void) print(" %d", p->pid); print("\n"); } + print("nrdy %d\n", nrdy); } void