M pc/clock.c => pc/clock.c +30 -21
@@ 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;
}
M pc/devvga.c => pc/devvga.c +30 -29
@@ 825,20 825,20 @@ screenload(Rectangle r, uchar *data, int tl, int l, int dolock)
data += l;
}
}else for(y=r.min.y; y<r.max.y; y++){
- 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;
+ 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<r.max.y; y++){
- 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;
+ 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)
M pc/vgas3.c => pc/vgas3.c +29 -4
@@ 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;
}
M port/portfns.h => port/portfns.h +1 -0
@@ 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*);
M port/proc.c => port/proc.c +7 -0
@@ 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