M carrera/trap.c => carrera/trap.c +10 -9
@@ 320,7 320,7 @@ intr(Ureg *ur)
{
static uchar devint;
ulong cause = ur->cause;
- ulong isr, vec;
+ ulong isr;
m->intr++;
cause &= INTR7|INTR6|INTR5|INTR4|INTR3|INTR2|INTR1|INTR0;
@@ 351,21 351,22 @@ intr(Ureg *ur)
cause &= ~INTR3;
}
- if(cause & INTR5)
- panic("EISA NMI\n");
-
if(cause & INTR2) {
isr = IO(ulong, R4030Isr);
if(isr) {
- iprint("R4030 Interrupt\n");
- iprint(" ISR #%lux\n", IO(ulong, R4030Isr));
- iprint(" ET #%lux\n", IO(ulong, R4030Et));
- iprint(" RFA #%lux\n", IO(ulong, R4030Rfa));
- iprint(" MFA #%lux\n", IO(ulong, R4030Mfa));
+ print("R4030 Interrupt PC %lux R31 %lux\n", ur->pc, ur->r31);
+ print(" ISR #%lux\n", IO(ulong, R4030Isr));
+ print(" ET #%lux\n", IO(ulong, R4030Et));
+ print(" RFA #%lux\n", IO(ulong, R4030Rfa));
+ print(" MFA #%lux\n", IO(ulong, R4030Mfa));
}
cause &= ~INTR2;
}
+ if(cause & INTR5)
+ panic("EISA NMI\n");
+
+
if(cause & INTR4) {
devint = IO(uchar, I386ack);
switch(devint) {
M pc/clock.c => pc/clock.c +33 -31
@@ 142,7 142,7 @@ void
clockinit(void)
{
int x, y; /* change in counter */
- int family, model, loops;
+ int family, model, loops, incr;
X86type *t;
/*
@@ 170,35 170,37 @@ clockinit(void)
outb(T0cntr, (Freq/HZ)); /* low byte */
outb(T0cntr, (Freq/HZ)>>8); /* high byte */
- /* use biggest loop that works */
- if(t->family == 3)
- loops = 10000;
- else
- loops = 30000;
+ /* find biggest loop that doesn't wrap */
+ incr = 16000000/(t->aalcycles*HZ*2);
+ for(loops = incr; loops < 64*1024; loops += incr) {
+
+ /*
+ * measure time for the loop
+ *
+ * MOVL loops,CX
+ * aaml1: AAM
+ * LOOP aaml1
+ *
+ * the time for the loop should be independent of external
+ * cache and memory system since it fits in the execution
+ * prefetch buffer.
+ *
+ */
+ outb(Tmode, Latch0);
+ x = inb(T0cntr);
+ x |= inb(T0cntr)<<8;
+ aamloop(loops);
+ outb(Tmode, Latch0);
+ y = inb(T0cntr);
+ y |= inb(T0cntr)<<8;
+ x -= y;
+
+ if(x < 0)
+ x += Freq/HZ;
- /*
- * measure time for the loop
- *
- * MOVL loops,CX
- * aaml1: AAM
- * LOOP aaml1
- *
- * the time for the loop should be independent of external
- * cache and memory system since it fits in the execution
- * prefetch buffer.
- *
- */
- outb(Tmode, Latch0);
- x = inb(T0cntr);
- x |= inb(T0cntr)<<8;
- aamloop(loops);
- outb(Tmode, Latch0);
- y = inb(T0cntr);
- y |= inb(T0cntr)<<8;
- x -= y;
-
- if(x < 0)
- x += 2^16;
+ if(x > Freq/(3*HZ))
+ break;
+ }
/*
* counter goes at twice the frequency, once per transition,
@@ 213,7 215,7 @@ clockinit(void)
loopconst = (cpufreq/1000)/t->aalcycles; /* AAM+LOOP's for 1 ms */
/*
- * add in possible .1% error and convert to MHz
+ * add in possible .2% error and convert to MHz
*/
- cpumhz = (cpufreq + cpufreq/1000)/1000000;
+ cpumhz = (cpufreq + cpufreq/500)/1000000;
}
M pc/devvga.c => pc/devvga.c +3 -15
@@ 60,7 60,7 @@ struct Vgacard
static void nopage(int);
static void cirruspage(int);
-static void et4000page(int);
+extern void et4000page(int);
extern void s3page(int);
Vgacard vgachips[] =
@@ 75,11 75,13 @@ Vgacard vgachips[] =
Vgacard *vgacard = &vgachips[0]; /* current vga card */
extern Hwgc bt485hwgc;
+extern Hwgc et4000hwgc;
extern Hwgc s3hwgc;
extern Hwgc tvp3020hwgc;
static Hwgc *hwcursor[] = {
&bt485hwgc,
+ &et4000hwgc,
&s3hwgc,
&tvp3020hwgc,
0,
@@ 1072,20 1074,6 @@ nopage(int page)
}
static void
-et4000page(int page)
-{
- uchar p;
-
- p = page & 0x0F;
- p |= p<<4;
- outb(0x3CD, p);
-
- p = (page & 0x30);
- p |= p>>4;
- outb(0x3CB, p);
-}
-
-static void
cirruspage(int page)
{
vgaxo(Grx, 0x09, page<<4);
A pc/vgaet4000.c => pc/vgaet4000.c +269 -0
@@ 0,0 1,269 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+#include <libg.h>
+#include "screen.h"
+#include "vga.h"
+
+extern Bitmap gscreen;
+extern Cursor curcursor;
+
+static Lock et4000pagelock;
+static ulong storage;
+static Point hotpoint;
+
+static void
+setet4000page(int page)
+{
+ uchar p;
+
+ p = page & 0x0F;
+ p |= p<<4;
+ outb(0x3CD, p);
+
+ p = (page & 0x30);
+ p |= p>>4;
+ outb(0x3CB, p);
+}
+
+static void
+disable(void)
+{
+ uchar imaF7;
+
+ outb(0x217A, 0xF7);
+ imaF7 = inb(0x217B) & ~0x80;
+ outb(0x217B, imaF7);
+}
+
+static void
+enable(void)
+{
+ uchar imaF7;
+
+ disable();
+
+ /*
+ * Configure CRTCB for Sprite, 64x64,
+ * CRTC pixel overlay.
+ */
+ outb(0x217A, 0xEF);
+ outb(0x217B, 0x02);
+
+ /*
+ * Cursor goes in the top left corner
+ * of the Sprite area, so the horizontal and
+ * vertical presets are 0.
+ */
+ outb(0x217A, 0xE2);
+ outb(0x217B, 0x00);
+ outb(0x217A, 0xE3);
+ outb(0x217B, 0x00);
+
+ outb(0x217A, 0xE6);
+ outb(0x217B, 0x00);
+ outb(0x217A, 0xE7);
+ outb(0x217B, 0x00);
+
+ /*
+ * Find a place for the cursor data in display memory.
+ * Must be on a "doubleword" boundary, but put it on a
+ * 1024-byte boundary so that there's no danger of it
+ * crossing a page.
+ */
+ storage = (gscreen.width*BY2WD*gscreen.r.max.y+1023)/1024;
+ storage *= 1024/4;
+ outb(0x217A, 0xE8);
+ outb(0x217B, storage & 0xFF);
+ outb(0x217A, 0xE9);
+ outb(0x217B, (storage>>8) & 0xFF);
+ outb(0x217A, 0xEA);
+ outb(0x217B, (storage>>16) & 0x0F);
+ storage *= 4;
+
+ /*
+ * Row offset in "quadwords". Must be 2 for Sprite.
+ * Bag the pixel-panning.
+ * Colour depth, must be 2 for Sprite.
+ */
+ outb(0x217A, 0xEB);
+ outb(0x217B, 0x02);
+ outb(0x217A, 0xEC);
+ outb(0x217B, 0x00);
+
+ outb(0x217A, 0xED);
+ outb(0x217B, 0x00);
+
+ outb(0x217A, 0xEE);
+ if(gscreen.ldepth == 3)
+ outb(0x217B, 0x01);
+ else
+ outb(0x217B, 0x00);
+
+ /*
+ * Enable the CRTCB/Sprite.
+ */
+ outb(0x217A, 0xF7);
+ imaF7 = inb(0x217B);
+ outb(0x217B, 0x80|imaF7);
+}
+
+static void
+load(Cursor *c)
+{
+ uchar p0, p1, *mem;
+ int i, x, y;
+ ushort p;
+
+ /*
+ * Lock the display memory so we can update the
+ * cursor bitmap if necessary.
+ */
+ lock(&et4000pagelock);
+ if(memcmp(c, &curcursor, sizeof(Cursor)) == 0){
+ outb(0x217A, 0xF7);
+ p0 = inb(0x217B);
+ outb(0x217B, 0x80|p0);
+ unlock(&et4000pagelock);
+ return;
+ }
+ memmove(&curcursor, 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();
+
+ setet4000page(storage>>16);
+ mem = ((uchar*)gscreen.base) + (storage & 0xFFFF);
+
+ /*
+ * Initialise the 64x64 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 mode gives the following truth table:
+ * p1 p0 colour
+ * 0 0 Sprite Colour 0 (defined as 0x00)
+ * 0 1 Sprite Colour 1 (defined as 0xFF)
+ * 1 0 Transparent (allow CRTC pixel pass through)
+ * 1 1 Invert (allow CRTC pixel invert through)
+ * Put the cursor into the top-left of the 64x64 array.
+ */
+ for(y = 0; y < 64; y++){
+ for(x = 0; x < 64/8; x++){
+ if(x < 16/8 && y < 16){
+ p0 = c->clr[x+y*2];
+ p1 = c->set[x+y*2];
+
+ p = 0x0000;
+ for(i = 0; i < 8; i++){
+ if(p0 & (1<<(7-i)))
+ ;
+ else if(p1 & (1<<(7-i)))
+ p |= 0x01<<(2*i);
+ else
+ p |= 0x02<<(2*i);
+ }
+ *mem++ = p & 0xFF;
+ *mem++ = (p>>8) & 0xFF;
+ }
+ else {
+ *mem++ = 0xAA;
+ *mem++ = 0xAA;
+ }
+ }
+ }
+
+ /*
+ * Set the cursor hotpoint and enable the cursor.
+ */
+ hotpoint = c->offset;
+ outb(0x217A, 0xF7);
+ p = inb(0x217B)|0x80;
+ outb(0x217B, p);
+
+ unlock(&et4000pagelock);
+}
+
+static int
+move(Point p)
+{
+ int x, xo, y, yo;
+
+ if(canlock(&et4000pagelock) == 0)
+ return 1;
+
+ /*
+ * Mustn't position the cursor offscreen even partially,
+ * or it disappears. Therefore, if x or y is -ve, adjust the
+ * cursor presets instead.
+ */
+ if((x = p.x+hotpoint.x) < 0){
+ xo = -x;
+ x = 0;
+ }
+ else
+ xo = 0;
+ if((y = p.y+hotpoint.y) < 0){
+ yo = -y;
+ y = 0;
+ }
+ else
+ yo = 0;
+
+ /*
+ * The cursor image is jerky if we don't do this.
+ * The cursor information is probably fetched from
+ * display memory during the horizontal blank active
+ * time and it doesn't like it if the coordinates
+ * are changed underneath.
+ */
+ while((vgai(Status1) & 0x08) == 0)
+ ;
+
+ outb(0x217A, 0xE2);
+ outb(0x217B, xo);
+
+ outb(0x217A, 0xE6);
+ outb(0x217B, yo);
+
+ outb(0x217A, 0xE1);
+ outb(0x217B, (x>>8) & 0xFF);
+ outb(0x217A, 0xE0);
+ outb(0x217B, x & 0xFF);
+ outb(0x217A, 0xE5);
+ outb(0x217B, (y>>8) & 0xFF);
+ outb(0x217A, 0xE4);
+ outb(0x217B, y & 0xFF);
+
+ unlock(&et4000pagelock);
+ return 0;
+}
+
+Hwgc et4000hwgc = {
+ "et4000hwgc",
+ enable,
+ load,
+ move,
+ disable,
+};
+
+void
+et4000page(int page)
+{
+ if(hwgc == &et4000hwgc){
+ lock(&et4000pagelock);
+ setet4000page(page);
+ unlock(&et4000pagelock);
+ }
+ else
+ setet4000page(page);
+}