URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/rtos/ecos-2.0/packages/services/gfx/mw/v2_0/src/contrib
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
/MWIN-TCW.PRJ
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
MWIN-TCW.PRJ
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: GPL/tpcal/transform.h
===================================================================
--- GPL/tpcal/transform.h (nonexistent)
+++ GPL/tpcal/transform.h (revision 174)
@@ -0,0 +1,37 @@
+/*
+ * transform.h
+ * Copyright (C) 1999 Bradley D. LaRonde
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+typedef struct
+{
+ MWPOINT screen, device;
+} CALIBRATION_PAIR;
+
+typedef struct
+{
+ CALIBRATION_PAIR center;
+ CALIBRATION_PAIR ul;
+ CALIBRATION_PAIR ur;
+ CALIBRATION_PAIR lr;
+ CALIBRATION_PAIR ll;
+} CALIBRATION_PAIRS;
+
+int CalcTransformationCoefficientsSimple(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc);
+int CalcTransformationCoefficientsBetter(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc);
+int CalcTransformationCoefficientsEvenBetter(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc);
+int CalcTransformationCoefficientsBest(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc);
Index: GPL/tpcal/tpcal.c
===================================================================
--- GPL/tpcal/tpcal.c (nonexistent)
+++ GPL/tpcal/tpcal.c (revision 174)
@@ -0,0 +1,363 @@
+/*
+ * Touch-panel calibration program
+ * Copyright (C) 1999 Bradley D. LaRonde
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include
+#include
+#include
+#include
+#include
+#include "windows.h"
+#include "mou_tp.h"
+#include "transform.h"
+
+static int xext, yext;
+static CALIBRATION_PAIRS cps;
+static CALIBRATION_PAIR* pcp = 0;
+
+void DrawAbout(HDC hdc, RECT r)
+{
+ const int ver_major = 0;
+ const int ver_minor = 5;
+ const char app_name[] = "Touch Panel Calibrator";
+ const char title[] = "%s, version %d.%d";
+ const char copyright[] = "(C) 1999 Bradley D. LaRonde ";
+ const char warranty[] = "ABSOLUTELY NO WARRANTY";
+ const char license1[] = "This is free software, and you are welcome to";
+ const char license2[] = "redistribute it under certain conditions.";
+
+ const int leading = 15;
+
+ char s[1024];
+
+ sprintf(s, title, app_name, ver_major, ver_minor);
+ SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
+ DrawText(hdc, s, -1, &r, DT_CENTER);
+
+ r.top += leading;
+ DrawText(hdc, copyright, -1, &r, DT_CENTER);
+
+ r.top += leading;
+ DrawText(hdc, warranty, -1, &r, DT_CENTER);
+
+ r.top += leading;
+ DrawText(hdc, license1, -1, &r, DT_CENTER);
+ r.top += leading;
+ DrawText(hdc, license2, -1, &r, DT_CENTER);
+}
+
+void DrawDone(HDC hdc, RECT r)
+{
+ const char donemsg[] = "Calibration is done!";
+ SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
+ DrawText(hdc, donemsg, -1, &r, DT_CENTER);
+}
+
+
+void DrawTarget(HDC hdc, POINT p)
+{
+ const int scale = 9;
+ const int center = 3;
+
+ // I never knew that Windows GDI always leaves off
+ // the last point in a line, and the right and bottom side of a rectangle.
+ // Why would they make use always figure +1? It isn't always obvious where
+ // +1 is (i.e. a line going at a 10 degree angle). Blech.
+ // I can only hope that there is some overwhelmingly compelling reason why.
+
+ Rectangle(hdc, p.x - center, p.y - center, p.x + center + 1, p.y + center + 1);
+
+ // scale
+ MoveToEx(hdc, p.x - scale, p.y, NULL);
+ LineTo(hdc, p.x + scale + 1, p.y);
+
+ MoveToEx(hdc, p.x, p.y - scale, NULL);
+ LineTo(hdc, p.x, p.y + scale + 1);
+}
+
+void DrawLabelAlign(HDC hdc, POINT p, LPCSTR psz, int align)
+{
+ RECT r;
+ const int w = 180;
+ const int h = 14;
+ const int m = 15;
+
+ switch(align)
+ {
+ case 1:
+ // right
+ r.left = p.x + m;
+ r.right = p.x + w + m;
+ r.top = p.y - (h/2);
+ r.bottom = p.y + (h/2);
+ break;
+
+ case 2:
+ // left
+ r.left = p.x - (w + m);
+ r.right = p.x - m;
+ r.top = p.y - (h/2);
+ r.bottom = p.y + (h/2);
+ break;
+
+ case 3:
+ // below
+ r.left = p.x - (w/2);
+ r.right = p.x + (w/2);
+ r.top = p.y + m;
+ r.bottom = p.y + m + h;
+ break;
+
+ default:
+ // at
+ r.left = p.x;
+ r.right = p.x + w;
+ r.top = p.y;
+ r.bottom = p.y + h;
+ break;
+ }
+
+ SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
+ DrawText(hdc, psz, -1, &r, DT_LEFT);
+}
+
+void DrawLabel(HDC hdc, POINT p, LPCSTR psz)
+{
+ if ( p.x < (xext * 1 / 4) )
+ return DrawLabelAlign(hdc, p, psz, 1);
+
+ if ( p.x > (xext * 3 / 4) )
+ return DrawLabelAlign(hdc, p, psz, 2);
+
+ return DrawLabelAlign(hdc, p, psz, 3);
+}
+
+POINT GetTarget(int n)
+{
+ const int inset = 10;
+ POINT p;
+
+ switch (n)
+ {
+ case 0:
+ p.x = xext / 2; p.y = yext / 2;
+ pcp = &cps.center;
+ break;
+
+ case 1:
+ p.x = inset; p.y = inset;
+ pcp = &cps.ul;
+ break;
+
+ case 2:
+ p.x = xext - inset; p.y = inset;
+ pcp = &cps.ur;
+ break;
+
+ case 3:
+ p.x = xext - inset; p.y = yext - inset;
+ pcp = &cps.lr;
+ break;
+
+ case 4:
+ p.x = inset; p.y = yext - inset;
+ pcp = &cps.ll;
+ break;
+
+ default:
+ // return a random target
+ p.x = random() / (RAND_MAX / xext);
+ p.y = random() / (RAND_MAX / yext);
+ pcp = 0;
+ break;
+ }
+
+ return p;
+}
+
+static int total_targets = 5;
+static int current_target = 0;
+static POINT current_target_location;
+
+void DoPaint(HDC hdc)
+{
+ const char szInstructions[] = "Please touch the center of the target.";
+
+ POINT p;
+ int i, n;
+ int old_rop;
+ POINT last = current_target_location;
+ HPEN hOldPen;
+
+ if (current_target == total_targets) {
+ RECT r = {10, yext/2, xext - 10, yext/2 + 40};
+ DrawDone(hdc, r);
+ return;
+ }
+
+ if (current_target == 0)
+ {
+ RECT r = {10, yext - 85, xext - 10, yext - 10};
+ DrawAbout(hdc, r);
+ }
+
+ current_target_location = GetTarget(current_target);
+
+ old_rop = SetROP2(hdc, R2_XORPEN);
+ hOldPen = SelectObject(hdc, GetStockObject(WHITE_PEN));
+
+ n = 20;
+ for (i=0; i < n; i++)
+ {
+ p.x = last.x + ((current_target_location.x - last.x) * i / n);
+ p.y = last.y + ((current_target_location.y - last.y) * i / n);
+ DrawTarget(hdc, p);
+ Sleep(60);
+ DrawTarget(hdc, p);
+ }
+
+ // final position
+ SetROP2(hdc, R2_COPYPEN);
+ SelectObject(hdc, GetStockObject(BLACK_PEN));
+
+ DrawTarget(hdc, current_target_location);
+ DrawLabel(hdc, current_target_location, szInstructions);
+
+ // put things back
+ SetROP2(hdc, old_rop);
+ SelectObject(hdc, hOldPen);
+}
+
+#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
+#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
+
+LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
+{
+ PAINTSTRUCT ps;
+ HDC hdc;
+
+ switch(msg) {
+ case WM_PAINT:
+ hdc = BeginPaint(hwnd, &ps);
+ DoPaint(hdc);
+ EndPaint(hwnd, &ps);
+ break;
+
+ case WM_NCHITTEST:
+ return HTCLIENT;
+
+ case WM_LBUTTONUP:
+ if ( pcp != 0 )
+ {
+ pcp->screen.x = current_target_location.x * TRANSFORMATION_UNITS_PER_PIXEL;
+ pcp->screen.y = current_target_location.y * TRANSFORMATION_UNITS_PER_PIXEL;
+ pcp->device.x = GET_X_LPARAM(lp);
+ pcp->device.y = GET_Y_LPARAM(lp);
+ }
+
+ if ( ++current_target == total_targets )
+ {
+ TRANSFORMATION_COEFFICIENTS tc;
+#if 0
+ CalcTransformationCoefficientsSimple(&cps, &tc);
+ printf("%d %d %d %d %d %d %d\n",
+ tc.a, tc.b, tc.c, tc.d, tc.e, tc.f, tc.s);
+ CalcTransformationCoefficientsBetter(&cps, &tc);
+ printf("%d %d %d %d %d %d %d\n",
+ tc.a, tc.b, tc.c, tc.d, tc.e, tc.f, tc.s);
+ CalcTransformationCoefficientsEvenBetter(&cps, &tc);
+ printf("%d %d %d %d %d %d %d\n",
+ tc.a, tc.b, tc.c, tc.d, tc.e, tc.f, tc.s);
+#endif
+ CalcTransformationCoefficientsBest(&cps, &tc);
+ printf("%d %d %d %d %d %d %d\n",
+ tc.a, tc.b, tc.c, tc.d, tc.e, tc.f, tc.s);
+ InvalidateRect(hwnd, NULL, TRUE);
+ UpdateWindow(hwnd);
+ PostQuitMessage(0);
+ break;
+ }
+ InvalidateRect(hwnd, NULL, TRUE);
+ UpdateWindow(hwnd);
+ break;
+
+ default:
+ return DefWindowProc(hwnd, msg, wp, lp);
+ }
+
+ return 0;
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
+{
+ WNDCLASS wc;
+ RECT r;
+ HWND hwnd;
+ MSG msg;
+ MWCOORD big;
+
+ srandom(time(NULL));
+
+ /* WndButtonRegister(NULL); */
+
+ wc.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
+ wc.lpfnWndProc = (WNDPROC)WndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = 0;
+ wc.hIcon = 0;
+ wc.hCursor = 0;
+ wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = "tpcal";
+ RegisterClass(&wc);
+
+ GetWindowRect(GetDesktopWindow(), &r);
+ xext = r.right;
+ yext = r.bottom;
+
+ hwnd = CreateWindowEx(0L, "tpcal", "Touch Panel Calibration",
+ WS_VISIBLE, 0, 0, xext, yext,
+ NULL, (HMENU)1, NULL, NULL);
+
+ // Don't restrict mouse much in order to handle uncalibrated points.
+ big = 1000000;
+ GdRestrictMouse(-big, -big, big, big);
+
+ // We want all mouse events - even ones outside our window.
+ SetCapture(hwnd);
+
+ while(GetMessage(&msg, NULL, 0, 0)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return 0;
+}
+
+int enable_pointing_coordinate_transform;
+
+int MwUserInit(int ac, char** av)
+{
+ enable_pointing_coordinate_transform = 0;
+
+ if ( ac > 1 )
+ total_targets = atol(av[1]);
+
+ return 0;
+}
+
Index: GPL/tpcal/VERSION
===================================================================
--- GPL/tpcal/VERSION (nonexistent)
+++ GPL/tpcal/VERSION (revision 174)
@@ -0,0 +1 @@
+0.5
Index: GPL/tpcal/transform.c
===================================================================
--- GPL/tpcal/transform.c (nonexistent)
+++ GPL/tpcal/transform.c (revision 174)
@@ -0,0 +1,295 @@
+/*
+ * transform.c
+ * Calculate coefficients for tranformation equation
+ * Copyright (C) 1999 Bradley D. LaRonde
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "windows.h"
+#include "mou_tp.h"
+#include "transform.h"
+
+int CalcTransformationCoefficientsSimple(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc)
+{
+ /*
+ * This is my simple way of calculating some of the coefficients -
+ * enough to do a simple scale and translate.
+ * It ignores any dependencies between axiis (rotation and/or skew).
+ */
+
+ int min_screen_x = pcp->ul.screen.x;
+ int min_screen_y = pcp->ul.screen.y;
+ int max_screen_x = pcp->lr.screen.x;
+ int max_screen_y = pcp->lr.screen.y;
+
+ int min_device_x = pcp->ul.device.x;
+ int min_device_y = pcp->ul.device.y;
+ int max_device_x = pcp->lr.device.x;
+ int max_device_y = pcp->lr.device.y;
+
+ ptc->s = (1 << 16);
+ ptc->a = ptc->s * (min_screen_x - max_screen_x) / (min_device_x - max_device_x);
+ ptc->b = 0;
+ ptc->c = (ptc->a * -min_device_x) + (ptc->s * min_screen_x);
+ ptc->d = 0;
+ ptc->e = ptc->s * (min_screen_y - max_screen_y) / (min_device_y - max_device_y);
+ ptc->f = (ptc->e * -min_device_y) + (ptc->s * min_screen_y);
+
+ return 0;
+}
+
+int CalcTransformationCoefficientsBetter(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc)
+{
+ /*
+ * Janus (the man) came up with a much better way
+ * to figure the coefficients. His original algorithm was written in MOO.
+ * Jay Carlson <> did the translation to C.
+ * This way takes into account inter-axis dependency like rotation and skew.
+ */
+
+ double vector[3][2] =
+ {
+ {pcp->ul.screen.x, pcp->ul.screen.y},
+ {pcp->ur.screen.x, pcp->ur.screen.y},
+ {pcp->lr.screen.x, pcp->lr.screen.y}
+ };
+
+ double matrix[3][3] =
+ {
+ {pcp->ul.device.x, pcp->ul.device.y, 1.0},
+ {pcp->ur.device.x, pcp->ur.device.y, 1.0},
+ {pcp->lr.device.x, pcp->lr.device.y, 1.0}
+ };
+
+ int i, j, r, k;
+ double p, q;
+
+ for (i = 0; i < 3; i++) {
+ p = matrix[i][i];
+
+ for (j = 0; j < 3; j++) {
+ matrix[i][j] = matrix[i][j] / p;
+ }
+
+ for (j = 0; j < 2; j++) {
+ vector[i][j] = vector[i][j] / p;
+ }
+
+ for (r = 0; r < 3; r++) {
+ if (r != i) {
+ q = matrix[r][i];
+
+ matrix[r][i] = 0.0;
+
+ for (k = i + 1; k < 3; k++) {
+ matrix[r][k] = matrix[r][k] - (q * matrix[i][k]);
+ }
+
+ for (k = 0; k < 2; k++) {
+ vector[r][k] = vector[r][k] - (q * vector[i][k]);
+ }
+ }
+ }
+ }
+
+ ptc->s = 1 << 16;
+ ptc->a = vector[0][0] * ptc->s;
+ ptc->b = vector[1][0] * ptc->s;
+ ptc->c = vector[2][0] * ptc->s;
+ ptc->d = vector[0][1] * ptc->s;
+ ptc->e = vector[1][1] * ptc->s;
+ ptc->f = vector[2][1] * ptc->s;
+
+ return 0;
+}
+
+int CalcTransformationCoefficientsEvenBetter(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc)
+{
+ /*
+ * Mike Klar <> added the an xy term to correct for trapezoidial distortion.
+ */
+
+ double vector[4][2] =
+ {
+ {pcp->ul.screen.x, pcp->ul.screen.y},
+ {pcp->ur.screen.x, pcp->ur.screen.y},
+ {pcp->lr.screen.x, pcp->lr.screen.y},
+ {pcp->ll.screen.x, pcp->ll.screen.y}
+ };
+
+ double matrix[4][4] =
+ {
+ {pcp->ul.device.x, pcp->ul.device.x * pcp->ul.device.y, pcp->ul.device.y, 1.0},
+ {pcp->ur.device.x, pcp->ur.device.x * pcp->ur.device.y, pcp->ur.device.y, 1.0},
+ {pcp->lr.device.x, pcp->lr.device.x * pcp->lr.device.y, pcp->lr.device.y, 1.0},
+ {pcp->ll.device.x, pcp->ll.device.x * pcp->ll.device.y, pcp->ll.device.y, 1.0}
+ };
+
+ int i, j, r, k;
+ double p, q;
+
+ for (i = 0; i < 4; i++) {
+ p = matrix[i][i];
+
+ for (j = 0; j < 4; j++) {
+ matrix[i][j] = matrix[i][j] / p;
+ }
+
+ for (j = 0; j < 2; j++) {
+ vector[i][j] = vector[i][j] / p;
+ }
+
+ for (r = 0; r < 4; r++) {
+ if (r != i) {
+ q = matrix[r][i];
+
+ matrix[r][i] = 0.0;
+
+ for (k = i + 1; k < 4; k++) {
+ matrix[r][k] = matrix[r][k] - (q * matrix[i][k]);
+ }
+
+ for (k = 0; k < 2; k++) {
+ vector[r][k] = vector[r][k] - (q * vector[i][k]);
+ }
+ }
+ }
+ }
+
+ /* I just drop the xy coefficient since it is so small. */
+ ptc->s = 1 << 16;
+ ptc->a = vector[0][0] * ptc->s;
+ ptc->b = vector[2][0] * ptc->s;
+ ptc->c = vector[3][0] * ptc->s;
+ ptc->d = vector[0][1] * ptc->s;
+ ptc->e = vector[2][1] * ptc->s;
+ ptc->f = vector[3][1] * ptc->s;
+
+ return 0;
+}
+
+int CalcTransformationCoefficientsBest(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc)
+{
+ /*
+ * Mike Klar <> came up with a best-fit solution that works best.
+ */
+
+ const int first_point = 0;
+ const int last_point = 4;
+ int i;
+
+ double Sx=0, Sy=0, Sxy=0, Sx2=0, Sy2=0, Sm=0, Sn=0, Smx=0, Smy=0, Snx=0, Sny=0, S=0;
+ double t1, t2, t3, t4, t5, t6, q;
+
+ /* cast the struct to an array - hacky but ok */
+ CALIBRATION_PAIR *cp = (CALIBRATION_PAIR*)pcp;
+
+ /*
+ * Do a best-fit calculation for as many points as we want, as
+ * opposed to an exact fit, which can only be done against 3 points.
+ *
+ * The following calculates various sumnations of the sample data
+ * coordinates. For purposes of naming convention, x and y
+ * refer to device coordinates, m and n refer to screen
+ * coordinates, S means sumnation. x2 and y2 are x squared and
+ * y squared, S by itself is just a count of points (= sumnation
+ * of 1).
+ */
+
+ for (i = first_point; i < last_point + 1; i++) {
+ Sx += cp[i].device.x;
+ Sy += cp[i].device.y;
+ Sxy += cp[i].device.x * cp[i].device.y;
+ Sx2 += cp[i].device.x * cp[i].device.x;
+ Sy2 += cp[i].device.y * cp[i].device.y;
+ Sm += cp[i].screen.x;
+ Sn += cp[i].screen.y;
+ Smx += cp[i].screen.x * cp[i].device.x;
+ Smy += cp[i].screen.x * cp[i].device.y;
+ Snx += cp[i].screen.y * cp[i].device.x;
+ Sny += cp[i].screen.y * cp[i].device.y;
+ S += 1;
+ }
+
+#if 0
+ printf("%f, %f, %f, %f, "
+ "%f, %f, %f, %f, "
+ "%f, %f, %f, %f\n",
+ Sx, Sy, Sxy, Sx2, Sy2, Sm, Sn, Smx, Smy, Snx, Sny, S);
+#endif
+
+ /*
+ * Next we solve the simultaneous equations (these equations minimize
+ * the sum of the square of the m and n error):
+ *
+ * | Sx2 Sxy Sx | | a d | | Smx Snx |
+ * | Sxy Sy2 Sy | * | b e | = | Smy Sny |
+ * | Sx Sy S | | c f | | Sm Sn |
+ *
+ * We could do the matrix solution in code, but that leads to several
+ * divide by 0 conditions for cases where the data is truly solvable
+ * (becuase those terms cancel out of the final solution), so we just
+ * give the final solution instread. t1 through t6 and q are just
+ * convenience variables for terms that are used repeatedly - we could
+ * calculate each of the coefficients directly at this point with a
+ * nasty long equation, but that would be extremly inefficient.
+ */
+
+ t1 = Sxy * Sy - Sx * Sy2;
+ t2 = Sxy * Sx - Sx2 * Sy;
+ t3 = Sx2 * Sy2 - Sxy * Sxy;
+ t4 = Sy2 * S - Sy * Sy;
+ t5 = Sx * Sy - Sxy * S;
+ t6 = Sx2 * S - Sx * Sx;
+
+ q = t1 * Sx + t2 * Sy + t3 * S;
+
+ /*
+ * If q = 0, then the data is unsolvable. This should only happen
+ * when there are not enough unique data points (less than 3 points
+ * will give infinite solutions), or at least one of the
+ * coefficients is infinite (which would indicate that the same
+ * device point represents an infinite area of the screen, probably
+ * as a result of the same device data point given for 2 different
+ * screen points). The first condition should never happen, since
+ * we're always feeding in at least 3 unique screen points. The
+ * second condition would probably indicate bad user input or the
+ * touchpanel device returning bad data.
+ */
+
+ if (q == 0)
+ return -1;
+
+ ptc->s = 1 << 16;
+ ptc->a = ((t4 * Smx + t5 * Smy + t1 * Sm) / q + 0.5/65536) * ptc->s;
+ ptc->b = ((t5 * Smx + t6 * Smy + t2 * Sm) / q + 0.5/65536) * ptc->s;
+ ptc->c = ((t1 * Smx + t2 * Smy + t3 * Sm) / q + 0.5/65536) * ptc->s;
+ ptc->d = ((t4 * Snx + t5 * Sny + t1 * Sn) / q + 0.5/65536) * ptc->s;
+ ptc->e = ((t5 * Snx + t6 * Sny + t2 * Sn) / q + 0.5/65536) * ptc->s;
+ ptc->f = ((t1 * Snx + t2 * Sny + t3 * Sn) / q + 0.5/65536) * ptc->s;
+
+ /*
+ * Finally, we check for overflow on the fp to integer conversion,
+ * which would also probably indicate bad data.
+ */
+
+ if ( (ptc->a == 0x80000000) || (ptc->b == 0x80000000) ||
+ (ptc->c == 0x80000000) || (ptc->d == 0x80000000) ||
+ (ptc->e == 0x80000000) || (ptc->f == 0x80000000) )
+ return -1;
+
+ return 0;
+}
+
Index: GPL/tpcal/Makefile
===================================================================
--- GPL/tpcal/Makefile (nonexistent)
+++ GPL/tpcal/Makefile (revision 174)
@@ -0,0 +1,13 @@
+#CC = mipsel-linux-gcc -msoft-float -s
+CC = gcc
+CFLAGS = -Wall -I../../../include -I../../../drivers -L../../../lib
+LIBS = -lmwin -lmwinlib -lmwengine -lmwdrivers -lmwfonts
+OBJECTS = tpcal.o transform.o
+
+all: tpcal
+
+tpcal: $(OBJECTS)
+ $(CC) $(CFLAGS) $(OBJECTS) $(LIBS) -o tpcal
+
+clean:
+ rm -f *.o tpcal
Index: readme.tc
===================================================================
--- readme.tc (nonexistent)
+++ readme.tc (revision 174)
@@ -0,0 +1,102 @@
+For compile Microwindows for DOS & TURBO C
+you should have the following:
+====================================================
+1. Microwin 0.87 - microwindows.censoft.com
+2. Turbo C++ ver. 1.0 or Borland C ver. 3.1
+
+
+You should do the following:
+----------------------------
+
+- copy mwin-tcn.prj to microwin\src\
+- copy mwin-tcw.prj to microwin\src\
+
+- run tc or bc IDE
+- load the project
+
+
+You should check the next:
+-------------------------
+
+- correct paths
+- settings defines in :
+ options | compiler | code generation - defines :
+
+ ERASEMOVE=1;
+ MSDOS=1;
+ DOS_TURBOC=1;
+
+
+MAKE !
+====================================================
+
+- mwin-pcw.prj = mwin demo
+- mwin-pcn.prj = nanox demo
+
+For nanox add next defines:
+ NONETWORK=1;
+ SCREEN_PIXTYPE=PF_PALETTE;
+
+
+! NOT all demos have been tested.
+====================================================
+
+The project for mwin demo must have next files:
+
+\DEMOS\MWIN\DEMO.C
+\DRIVERS\GENFONT.C
+\DRIVERS\KBD_TC.C
+\DRIVERS\MOU_DOS.C
+\DRIVERS\SCR_TC.C
+\FONTS\ROM8X16.C
+\FONTS\ROM8X8.C
+\FONTS\WINFRE~1.C
+\FONTS\WINFRE~2.C
+\ENGINE\DEVCLIP.C
+\ENGINE\DEVDRAW.C
+\ENGINE\DEVKBD.C
+\ENGINE\DEVMOUSE.C
+\ENGINE\DEVPAL1.C
+\ENGINE\DEVPAL2.C
+\ENGINE\DEVPAL4.C
+\MWIN\WINCLIP.C
+\MWIN\WINDEFW.C
+\MWIN\WINEVENT.C
+\MWIN\WINEXPOS.C
+\MWIN\WINMAIN.C
+\MWIN\WINUSER.C
+\MWIN\WINGDI.C
+\MWIN\LIST.C
+\MWIN\WINLIB\BUTTON.C
+\MWIN\WINLIB\DRAW3D.C
+\MWIN\WINLIB\FASTFILL.C
+\MWIN\WINLIB\GRAPH3D.C
+\MWIN\WINLIB\INSETR.C
+\MWIN\WINLIB\PTINSID.C
+\MWIN\BMP\CS1.C
+
+The project for nanox demo must have next files:
+
+\DEMOS\NANOX\DEMO.C
+\DRIVERS\GENFONT.C
+\DRIVERS\KBD_TC.C
+\DRIVERS\MOU_DOS.C
+\DRIVERS\SCR_TC.C
+\FONTS\ROM8X16.C
+\FONTS\ROM8X8.C
+\FONTS\WINFRE~1.C
+\ENGINE\DEVCLIP.C
+\ENGINE\DEVDRAW.C
+\ENGINE\DEVKBD.C
+\ENGINE\DEVMOUSE.C
+\ENGINE\DEVPAL1.C
+\ENGINE\DEVPAL2.C
+\ENGINE\DEVPAL4.C
+\NANOX\SRVEVENT.C
+\NANOX\SRVFUNC.C
+\NANOX\SRVMAIN.C
+\NANOX\SRVUTIL.C
+\NANOX\STUBS.C
+
+====================================================
+Victor Rogachev
Index: ntimers.c
===================================================================
--- ntimers.c (nonexistent)
+++ ntimers.c (revision 174)
@@ -0,0 +1,29 @@
+
+void
+GsAddTimer(struct GsTimer* newtimer) {
+ int i;
+ struct GsTimer* curTimer;
+ if(our_timers.numof++>0) {
+ curTimer=our_timer->head;
+ for(curTimer=our_timer->head;curTimer!=NULL;curTimer=curTimer->next) {
+ if(curTimer->due>newtimer->due) { /* time to file it away... */
+ if(our_timer->head==curTimer) { /* put it at the beginning... */
+ newtimer->next=our_timer->head;
+ our_timer->head=newtimer;
+ return;
+ } /* else put it in the middle... */
+ newtimer->next=curTimer;
+ prevTimer->next=newtimer;
+ return;
+ }
+ prevTimer=curTimer;
+ } /* else put it at the end... */
+ our_timer->tail->next=newtimer;
+ our_timer->tail=newtimer;
+ newtimer->next=NULL;
+ return;
+ } /* else... hey it's the first timer! */
+ our_timer->head=newtimer;
+ our_timer->tail=newtimer;
+ newtimer->next=NULL;
+}
Index: ptyfix2.txt
===================================================================
--- ptyfix2.txt (nonexistent)
+++ ptyfix2.txt (revision 174)
@@ -0,0 +1,86 @@
+
+--- demos/microwin/mterm.c.old Fri Dec 3 07:03:39 1999
++++ demos/microwin/mterm.c Fri Dec 3 07:16:23 1999
+@@ -248,15 +248,16 @@
+ char * argv[2];
+
+ again:
+- sprintf(pty_name, "/dev/ptyp%d", n);
+- if ((tfd = open(pty_name, O_RDWR | O_NONBLOCK)) < 0) {
+- if ((errno == EBUSY) && (n < 3)) {
+- ++n;
+- goto again;
+- }
+- fprintf(stderr, "Can't create pty %s\n", pty_name);
++ if ((tfd = getpt())<0) {
++ fprintf(stderr, "Can't create master pty\n");
+ return -1;
+ }
++
++ if (grantpt(tfd))
++ perror("failure");
++ if (unlockpt(tfd))
++ perror("failure");
++
+ signal(SIGCHLD, ptysignaled);
+ signal(SIGINT, ptysignaled);
+ if ((pid = fork()) == -1) {
+@@ -264,13 +265,13 @@
+ return -1;
+ }
+ if (!pid) {
++ ptsname_r(tfd, pty_name, 12);
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+ close(tfd);
+
+ setsid();
+- pty_name[5] = 't';
+ if ((tfd = open(pty_name, O_RDWR)) < 0) {
+ fprintf(stderr, "Child: Can't open pty %s\n", pty_name);
+ exit(1);
+--- demos/nanox/nterm.c.old Fri Dec 3 07:03:39 1999
++++ demos/nanox/nterm.c Fri Dec 3 07:16:20 1999
+@@ -162,15 +162,16 @@
+ pid_t pid;
+
+ again:
+- sprintf(pty_name, "/dev/ptyp%d", n);
+- if ((tfd = open(pty_name, O_RDWR | O_NONBLOCK)) < 0) {
+- if ((errno == EBUSY || errno == EIO) && n < 10) {
+- n++;
+- goto again;
+- }
+- fprintf(stderr, "Can't create pty %s\n", pty_name);
++ if ((tfd = getpt())<0) {
++ fprintf(stderr, "Can't create master pty\n");
+ return -1;
+ }
++
++ if (grantpt(tfd))
++ perror("failure");
++ if (unlockpt(tfd))
++ perror("failure");
++
+ signal(SIGCHLD, sigchild);
+ signal(SIGINT, sigchild);
+ if ((pid = fork()) == -1) {
+@@ -178,13 +179,13 @@
+ return -1;
+ }
+ if (!pid) {
++ ptsname_r(tfd, pty_name, 12);
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+ close(tfd);
+
+ setsid();
+- pty_name[5] = 't';
+ if ((tfd = open(pty_name, O_RDWR)) < 0) {
+ fprintf(stderr, "Child: Can't open pty %s\n", pty_name);
+ exit(1);
+
+
+--
\ No newline at end of file
Index: djgpp/readme.dj
===================================================================
--- djgpp/readme.dj (nonexistent)
+++ djgpp/readme.dj (revision 174)
@@ -0,0 +1,41 @@
+For compiliing Microwindows to DOS + DJGPP you should have the following:
+=====================================================================
+1. Microwin 0.89 pre7 - (microwindows.org)
+2. DJGPP ver. 2.01 - (www.delorie.com)
+3. GRX ver. 2.3 - (www.gnu.de/software/grx or www.delorie.com)
+
+
+You should do the following:
+===============================
+1. copy Configs/config.dj to src/config
+
+
+do MAKE !!!
+===============
+
+I made it on Windows 95.
+
+File grx20.h should be in djgpp\include and file libgrx20.a
+should be in djgpp\lib.
+
+For using long file names you should set LFN=y in file djgpp.env
+under Windows 95, or rename some files to 8.3 under DOS.
+
+For NANOXDEMO use LINK_APP_INTO_SERVER.
+
+! NOT all demos have been tested (or debugged) for DJGPP.
+
+:-( :-( :-( :-( :-( :-( :-( :-( :-( :-( :-( :-(
+
+Sorry, but you have to exclude from src/demos/nanox makefile
+next files:
+
+nxterm.c, npanel.c, ntetris.c, launcher.c, nxview.c, slider.c
+
+TO DO : fix next files :
+
+nxterm.c, npanel.c, ntetris.c, launcher.c, nxview.c, slider.c
+
+===============================================
+
+Victor Rogachev
Index: jpeg/README.txt
===================================================================
--- jpeg/README.txt (nonexistent)
+++ jpeg/README.txt (revision 174)
@@ -0,0 +1,25 @@
+To enable jpeg support in nanogui:
+
+- Download libjpeg source tarball at http://www.ijg.org
+- Untar the tarball with tar -zxf
+
+In the jpeg directory, setup your compilation environment.
+Here are the typical steps for linux:
+
+- cp jconfig.doc jconfig.h
+- cp makefile.ansi Makefile
+- Open the Makefile and delete the jconfig.h: target
+- Don't forget to setup the right cc tools if you cross-compile!
+- type 'make'
+
+In the config file:
+
+- Enable the HAVE_JPEG_SUPPORT definition
+- set the INCJPEG to the jpeg directory
+- set the LIBJPEG to the jpeg directory
+- compile the project
+
+See demo3 if you want to see an example demo.
+
+Martin Jolcoeur
+martinj@visuaide.com
Index: MWIN-TCN.PRJ
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: MWIN-TCN.PRJ
===================================================================
--- MWIN-TCN.PRJ (nonexistent)
+++ MWIN-TCN.PRJ (revision 174)
MWIN-TCN.PRJ
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: README.freebsd
===================================================================
--- README.freebsd (nonexistent)
+++ README.freebsd (revision 174)
@@ -0,0 +1,17 @@
+I have added files to this package to get it to run on a FreeBSD
+console. Some changes, particularly to the Makefiles are not particularly
+clean, and could probably be done a lot better (but hey, it's what I got
+done in about a day d8)
+
+2000/07/01
+I've added a terminal 'wterm'. At least it has a termcap so you can
+run curses based stuff, and it scrolls (scroll speed depends on the
+speed of your blitter, the FreeBSD blitter is completely stupid at
+the moment).
+
+--
+Totally Holistic Enterprises Internet| P:+61 7 3870 0066 | Andrew
+The Internet (Aust) Pty Ltd | F:+61 7 3870 4477 | Milton
+ACN: 082 081 472 | M:+61 416 022 411 |72 Col .Sig
+PO Box 837 Indooroopilly QLD 4068 |akm@theinternet.com.au|Specialist
+
Index: ntimers.h
===================================================================
--- ntimers.h (nonexistent)
+++ ntimers.h (revision 174)
@@ -0,0 +1,19 @@
+#ifndef __NTIMER_H__
+#define __NTIMER_H__
+
+struct GsTimer {
+ struct GsTimer* next;
+ long due;
+ void* some_func;
+ void* some_args;
+};
+
+struct GsTimerHolder {
+ struct GsTimer* head;
+ struct GsTimer* tail;
+ int numof;
+};
+
+
+
+#endif
Index: BSD/bcopy.s
===================================================================
--- BSD/bcopy.s (nonexistent)
+++ BSD/bcopy.s (revision 174)
@@ -0,0 +1,1580 @@
+Hi,
+
+The following code is the file support.s from the FreeBSD 2.6
+distribution for i386. I included the entire file so you can
+pick and choose as you like and you can pick up the license.
+There's a generic bcopy that does overlapping, uses rep movs
+in the largest chunk possible, etc. That might do the trick.
+There's a few macros around but hopefully you can decipher
+them.
+
+Later,
+FM
+
+--
+Frank W. Miller
+Cornfed Systems Inc
+www.cornfed.com
+
+
+--
+/*-
+ * Copyright (c) 1993 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: bcopy.s,v 1.1.1.1 2004-02-14 13:34:41 phoenix Exp $
+ */
+
+#include "npx.h"
+#include "opt_cpu.h"
+
+#include
+#include
+#include
+#include
+
+#include "assym.s"
+
+#define KDSEL 0x10 /* kernel data selector */
+#define IDXSHIFT 10
+
+ .data
+ .globl _bcopy_vector
+_bcopy_vector:
+ .long _generic_bcopy
+ .globl _bzero
+_bzero:
+ .long _generic_bzero
+ .globl _copyin_vector
+_copyin_vector:
+ .long _generic_copyin
+ .globl _copyout_vector
+_copyout_vector:
+ .long _generic_copyout
+ .globl _ovbcopy_vector
+_ovbcopy_vector:
+ .long _generic_bcopy
+#if defined(I586_CPU) && NNPX > 0
+kernel_fpu_lock:
+ .byte 0xfe
+ .space 3
+#endif
+
+ .text
+
+/*
+ * bcopy family
+ * void bzero(void *buf, u_int len)
+ */
+
+ENTRY(generic_bzero)
+ pushl %edi
+ movl 8(%esp),%edi
+ movl 12(%esp),%ecx
+ xorl %eax,%eax
+ shrl $2,%ecx
+ cld
+ rep
+ stosl
+ movl 12(%esp),%ecx
+ andl $3,%ecx
+ rep
+ stosb
+ popl %edi
+ ret
+
+#if defined(I486_CPU)
+ENTRY(i486_bzero)
+ movl 4(%esp),%edx
+ movl 8(%esp),%ecx
+ xorl %eax,%eax
+/*
+ * do 64 byte chunks first
+ *
+ * XXX this is probably over-unrolled at least for DX2's
+ */
+2:
+ cmpl $64,%ecx
+ jb 3f
+ movl %eax,(%edx)
+ movl %eax,4(%edx)
+ movl %eax,8(%edx)
+ movl %eax,12(%edx)
+ movl %eax,16(%edx)
+ movl %eax,20(%edx)
+ movl %eax,24(%edx)
+ movl %eax,28(%edx)
+ movl %eax,32(%edx)
+ movl %eax,36(%edx)
+ movl %eax,40(%edx)
+ movl %eax,44(%edx)
+ movl %eax,48(%edx)
+ movl %eax,52(%edx)
+ movl %eax,56(%edx)
+ movl %eax,60(%edx)
+ addl $64,%edx
+ subl $64,%ecx
+ jnz 2b
+ ret
+
+/*
+ * do 16 byte chunks
+ */
+ SUPERALIGN_TEXT
+3:
+ cmpl $16,%ecx
+ jb 4f
+ movl %eax,(%edx)
+ movl %eax,4(%edx)
+ movl %eax,8(%edx)
+ movl %eax,12(%edx)
+ addl $16,%edx
+ subl $16,%ecx
+ jnz 3b
+ ret
+
+/*
+ * do 4 byte chunks
+ */
+ SUPERALIGN_TEXT
+4:
+ cmpl $4,%ecx
+ jb 5f
+ movl %eax,(%edx)
+ addl $4,%edx
+ subl $4,%ecx
+ jnz 4b
+ ret
+
+/*
+ * do 1 byte chunks
+ * a jump table seems to be faster than a loop or more range reductions
+ *
+ * XXX need a const section for non-text
+ */
+ .data
+jtab:
+ .long do0
+ .long do1
+ .long do2
+ .long do3
+
+ .text
+ SUPERALIGN_TEXT
+5:
+ jmp jtab(,%ecx,4)
+
+ SUPERALIGN_TEXT
+do3:
+ movw %ax,(%edx)
+ movb %al,2(%edx)
+ ret
+
+ SUPERALIGN_TEXT
+do2:
+ movw %ax,(%edx)
+ ret
+
+ SUPERALIGN_TEXT
+do1:
+ movb %al,(%edx)
+ ret
+
+ SUPERALIGN_TEXT
+do0:
+ ret
+#endif
+
+#if defined(I586_CPU) && NNPX > 0
+ENTRY(i586_bzero)
+ movl 4(%esp),%edx
+ movl 8(%esp),%ecx
+
+ /*
+ * The FPU register method is twice as fast as the integer register
+ * method unless the target is in the L1 cache and we pre-allocate a
+ * cache line for it (then the integer register method is 4-5 times
+ * faster). However, we never pre-allocate cache lines, since that
+ * would make the integer method 25% or more slower for the common
+ * case when the target isn't in either the L1 cache or the L2 cache.
+ * Thus we normally use the FPU register method unless the overhead
+ * would be too large.
+ */
+ cmpl $256,%ecx /* empirical; clts, fninit, smsw cost a lot */
+ jb intreg_i586_bzero
+
+ /*
+ * The FPU registers may belong to an application or to fastmove()
+ * or to another invocation of bcopy() or ourself in a higher level
+ * interrupt or trap handler. Preserving the registers is
+ * complicated since we avoid it if possible at all levels. We
+ * want to localize the complications even when that increases them.
+ * Here the extra work involves preserving CR0_TS in TS.
+ * `npxproc != NULL' is supposed to be the condition that all the
+ * FPU resources belong to an application, but npxproc and CR0_TS
+ * aren't set atomically enough for this condition to work in
+ * interrupt handlers.
+ *
+ * Case 1: FPU registers belong to the application: we must preserve
+ * the registers if we use them, so we only use the FPU register
+ * method if the target size is large enough to amortize the extra
+ * overhead for preserving them. CR0_TS must be preserved although
+ * it is very likely to end up as set.
+ *
+ * Case 2: FPU registers belong to fastmove(): fastmove() currently
+ * makes the registers look like they belong to an application so
+ * that cpu_switch() and savectx() don't have to know about it, so
+ * this case reduces to case 1.
+ *
+ * Case 3: FPU registers belong to the kernel: don't use the FPU
+ * register method. This case is unlikely, and supporting it would
+ * be more complicated and might take too much stack.
+ *
+ * Case 4: FPU registers don't belong to anyone: the FPU registers
+ * don't need to be preserved, so we always use the FPU register
+ * method. CR0_TS must be preserved although it is very likely to
+ * always end up as clear.
+ */
+ cmpl $0,_npxproc
+ je i586_bz1
+ cmpl $256+184,%ecx /* empirical; not quite 2*108 more */
+ jb intreg_i586_bzero
+ sarb $1,kernel_fpu_lock
+ jc intreg_i586_bzero
+ smsw %ax
+ clts
+ subl $108,%esp
+ fnsave 0(%esp)
+ jmp i586_bz2
+
+i586_bz1:
+ sarb $1,kernel_fpu_lock
+ jc intreg_i586_bzero
+ smsw %ax
+ clts
+ fninit /* XXX should avoid needing this */
+i586_bz2:
+ fldz
+
+ /*
+ * Align to an 8 byte boundary (misalignment in the main loop would
+ * cost a factor of >= 2). Avoid jumps (at little cost if it is
+ * already aligned) by always zeroing 8 bytes and using the part up
+ * to the _next_ alignment position.
+ */
+ fstl 0(%edx)
+ addl %edx,%ecx /* part of %ecx -= new_%edx - %edx */
+ addl $8,%edx
+ andl $~7,%edx
+ subl %edx,%ecx
+
+ /*
+ * Similarly align `len' to a multiple of 8.
+ */
+ fstl -8(%edx,%ecx)
+ decl %ecx
+ andl $~7,%ecx
+
+ /*
+ * This wouldn't be any faster if it were unrolled, since the loop
+ * control instructions are much faster than the fstl and/or done
+ * in parallel with it so their overhead is insignificant.
+ */
+fpureg_i586_bzero_loop:
+ fstl 0(%edx)
+ addl $8,%edx
+ subl $8,%ecx
+ cmpl $8,%ecx
+ jae fpureg_i586_bzero_loop
+
+ cmpl $0,_npxproc
+ je i586_bz3
+ frstor 0(%esp)
+ addl $108,%esp
+ lmsw %ax
+ movb $0xfe,kernel_fpu_lock
+ ret
+
+i586_bz3:
+ fstpl %st(0)
+ lmsw %ax
+ movb $0xfe,kernel_fpu_lock
+ ret
+
+intreg_i586_bzero:
+ /*
+ * `rep stos' seems to be the best method in practice for small
+ * counts. Fancy methods usually take too long to start up due
+ * to cache and BTB misses.
+ */
+ pushl %edi
+ movl %edx,%edi
+ xorl %eax,%eax
+ shrl $2,%ecx
+ cld
+ rep
+ stosl
+ movl 12(%esp),%ecx
+ andl $3,%ecx
+ jne 1f
+ popl %edi
+ ret
+
+1:
+ rep
+ stosb
+ popl %edi
+ ret
+#endif /* I586_CPU && NNPX > 0 */
+
+/* fillw(pat, base, cnt) */
+ENTRY(fillw)
+ pushl %edi
+ movl 8(%esp),%eax
+ movl 12(%esp),%edi
+ movl 16(%esp),%ecx
+ cld
+ rep
+ stosw
+ popl %edi
+ ret
+
+ENTRY(bcopyb)
+bcopyb:
+ pushl %esi
+ pushl %edi
+ movl 12(%esp),%esi
+ movl 16(%esp),%edi
+ movl 20(%esp),%ecx
+ movl %edi,%eax
+ subl %esi,%eax
+ cmpl %ecx,%eax /* overlapping && src < dst? */
+ jb 1f
+ cld /* nope, copy forwards */
+ rep
+ movsb
+ popl %edi
+ popl %esi
+ ret
+
+ ALIGN_TEXT
+1:
+ addl %ecx,%edi /* copy backwards. */
+ addl %ecx,%esi
+ decl %edi
+ decl %esi
+ std
+ rep
+ movsb
+ popl %edi
+ popl %esi
+ cld
+ ret
+
+ENTRY(bcopy)
+ MEXITCOUNT
+ jmp *_bcopy_vector
+
+ENTRY(ovbcopy)
+ MEXITCOUNT
+ jmp *_ovbcopy_vector
+
+/*
+ * generic_bcopy(src, dst, cnt)
+ * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
+ */
+ENTRY(generic_bcopy)
+ pushl %esi
+ pushl %edi
+ movl 12(%esp),%esi
+ movl 16(%esp),%edi
+ movl 20(%esp),%ecx
+
+ movl %edi,%eax
+ subl %esi,%eax
+ cmpl %ecx,%eax /* overlapping && src < dst? */
+ jb 1f
+
+ shrl $2,%ecx /* copy by 32-bit words */
+ cld /* nope, copy forwards */
+ rep
+ movsl
+ movl 20(%esp),%ecx
+ andl $3,%ecx /* any bytes left? */
+ rep
+ movsb
+ popl %edi
+ popl %esi
+ ret
+
+ ALIGN_TEXT
+1:
+ addl %ecx,%edi /* copy backwards */
+ addl %ecx,%esi
+ decl %edi
+ decl %esi
+ andl $3,%ecx /* any fractional bytes? */
+ std
+ rep
+ movsb
+ movl 20(%esp),%ecx /* copy remainder by 32-bit words */
+ shrl $2,%ecx
+ subl $3,%esi
+ subl $3,%edi
+ rep
+ movsl
+ popl %edi
+ popl %esi
+ cld
+ ret
+
+#if defined(I586_CPU) && NNPX > 0
+ENTRY(i586_bcopy)
+ pushl %esi
+ pushl %edi
+ movl 12(%esp),%esi
+ movl 16(%esp),%edi
+ movl 20(%esp),%ecx
+
+ movl %edi,%eax
+ subl %esi,%eax
+ cmpl %ecx,%eax /* overlapping && src < dst? */
+ jb 1f
+
+ cmpl $1024,%ecx
+ jb small_i586_bcopy
+
+ sarb $1,kernel_fpu_lock
+ jc small_i586_bcopy
+ cmpl $0,_npxproc
+ je i586_bc1
+ smsw %dx
+ clts
+ subl $108,%esp
+ fnsave 0(%esp)
+ jmp 4f
+
+i586_bc1:
+ smsw %dx
+ clts
+ fninit /* XXX should avoid needing this */
+
+ ALIGN_TEXT
+4:
+ pushl %ecx
+#define DCACHE_SIZE 8192
+ cmpl $(DCACHE_SIZE-512)/2,%ecx
+ jbe 2f
+ movl $(DCACHE_SIZE-512)/2,%ecx
+2:
+ subl %ecx,0(%esp)
+ cmpl $256,%ecx
+ jb 5f /* XXX should prefetch if %ecx >= 32 */
+ pushl %esi
+ pushl %ecx
+ ALIGN_TEXT
+3:
+ movl 0(%esi),%eax
+ movl 32(%esi),%eax
+ movl 64(%esi),%eax
+ movl 96(%esi),%eax
+ movl 128(%esi),%eax
+ movl 160(%esi),%eax
+ movl 192(%esi),%eax
+ movl 224(%esi),%eax
+ addl $256,%esi
+ subl $256,%ecx
+ cmpl $256,%ecx
+ jae 3b
+ popl %ecx
+ popl %esi
+5:
+ ALIGN_TEXT
+large_i586_bcopy_loop:
+ fildq 0(%esi)
+ fildq 8(%esi)
+ fildq 16(%esi)
+ fildq 24(%esi)
+ fildq 32(%esi)
+ fildq 40(%esi)
+ fildq 48(%esi)
+ fildq 56(%esi)
+ fistpq 56(%edi)
+ fistpq 48(%edi)
+ fistpq 40(%edi)
+ fistpq 32(%edi)
+ fistpq 24(%edi)
+ fistpq 16(%edi)
+ fistpq 8(%edi)
+ fistpq 0(%edi)
+ addl $64,%esi
+ addl $64,%edi
+ subl $64,%ecx
+ cmpl $64,%ecx
+ jae large_i586_bcopy_loop
+ popl %eax
+ addl %eax,%ecx
+ cmpl $64,%ecx
+ jae 4b
+
+ cmpl $0,_npxproc
+ je i586_bc2
+ frstor 0(%esp)
+ addl $108,%esp
+i586_bc2:
+ lmsw %dx
+ movb $0xfe,kernel_fpu_lock
+
+/*
+ * This is a duplicate of the main part of generic_bcopy. See the comments
+ * there. Jumping into generic_bcopy would cost a whole 0-1 cycles and
+ * would mess up high resolution profiling.
+ */
+ ALIGN_TEXT
+small_i586_bcopy:
+ shrl $2,%ecx
+ cld
+ rep
+ movsl
+ movl 20(%esp),%ecx
+ andl $3,%ecx
+ rep
+ movsb
+ popl %edi
+ popl %esi
+ ret
+
+ ALIGN_TEXT
+1:
+ addl %ecx,%edi
+ addl %ecx,%esi
+ decl %edi
+ decl %esi
+ andl $3,%ecx
+ std
+ rep
+ movsb
+ movl 20(%esp),%ecx
+ shrl $2,%ecx
+ subl $3,%esi
+ subl $3,%edi
+ rep
+ movsl
+ popl %edi
+ popl %esi
+ cld
+ ret
+#endif /* I586_CPU && NNPX > 0 */
+
+/*
+ * Note: memcpy does not support overlapping copies
+ */
+ENTRY(memcpy)
+ pushl %edi
+ pushl %esi
+ movl 12(%esp),%edi
+ movl 16(%esp),%esi
+ movl 20(%esp),%ecx
+ movl %edi,%eax
+ shrl $2,%ecx /* copy by 32-bit words */
+ cld /* nope, copy forwards */
+ rep
+ movsl
+ movl 20(%esp),%ecx
+ andl $3,%ecx /* any bytes left? */
+ rep
+ movsb
+ popl %esi
+ popl %edi
+ ret
+
+
+/*****************************************************************************/
+/* copyout and fubyte family */
+/*****************************************************************************/
+/*
+ * Access user memory from inside the kernel. These routines and possibly
+ * the math- and DOS emulators should be the only places that do this.
+ *
+ * We have to access the memory with user's permissions, so use a segment
+ * selector with RPL 3. For writes to user space we have to additionally
+ * check the PTE for write permission, because the 386 does not check
+ * write permissions when we are executing with EPL 0. The 486 does check
+ * this if the WP bit is set in CR0, so we can use a simpler version here.
+ *
+ * These routines set curpcb->onfault for the time they execute. When a
+ * protection violation occurs inside the functions, the trap handler
+ * returns to *curpcb->onfault instead of the function.
+ */
+
+/* copyout(from_kernel, to_user, len) */
+ENTRY(copyout)
+ MEXITCOUNT
+ jmp *_copyout_vector
+
+ENTRY(generic_copyout)
+ movl _curpcb,%eax
+ movl $copyout_fault,PCB_ONFAULT(%eax)
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+ movl 16(%esp),%esi
+ movl 20(%esp),%edi
+ movl 24(%esp),%ebx
+ testl %ebx,%ebx /* anything to do? */
+ jz done_copyout
+
+ /*
+ * Check explicitly for non-user addresses. If 486 write protection
+ * is being used, this check is essential because we are in kernel
+ * mode so the h/w does not provide any protection against writing
+ * kernel addresses.
+ */
+
+ /*
+ * First, prevent address wrapping.
+ */
+ movl %edi,%eax
+ addl %ebx,%eax
+ jc copyout_fault
+/*
+ * XXX STOP USING VM_MAXUSER_ADDRESS.
+ * It is an end address, not a max, so every time it is used correctly it
+ * looks like there is an off by one error, and of course it caused an off
+ * by one error in several places.
+ */
+ cmpl $VM_MAXUSER_ADDRESS,%eax
+ ja copyout_fault
+
+#if defined(I386_CPU)
+
+#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
+ cmpl $CPUCLASS_386,_cpu_class
+ jne 3f
+#endif
+/*
+ * We have to check each PTE for user write permission.
+ * The checking may cause a page fault, so it is important to set
+ * up everything for return via copyout_fault before here.
+ */
+ /* compute number of pages */
+ movl %edi,%ecx
+ andl $PAGE_MASK,%ecx
+ addl %ebx,%ecx
+ decl %ecx
+ shrl $IDXSHIFT+2,%ecx
+ incl %ecx
+
+ /* compute PTE offset for start address */
+ movl %edi,%edx
+ shrl $IDXSHIFT,%edx
+ andb $0xfc,%dl
+
+1:
+ /* check PTE for each page */
+ leal _PTmap(%edx),%eax
+ shrl $IDXSHIFT,%eax
+ andb $0xfc,%al
+ testb $PG_V,_PTmap(%eax) /* PTE page must be valid */
+ je 4f
+ movb _PTmap(%edx),%al
+ andb $PG_V|PG_RW|PG_U,%al /* page must be valid and user writable */
+ cmpb $PG_V|PG_RW|PG_U,%al
+ je 2f
+
+4:
+ /* simulate a trap */
+ pushl %edx
+ pushl %ecx
+ shll $IDXSHIFT,%edx
+ pushl %edx
+ call _trapwrite /* trapwrite(addr) */
+ popl %edx
+ popl %ecx
+ popl %edx
+
+ testl %eax,%eax /* if not ok, return EFAULT */
+ jnz copyout_fault
+
+2:
+ addl $4,%edx
+ decl %ecx
+ jnz 1b /* check next page */
+#endif /* I386_CPU */
+
+ /* bcopy(%esi, %edi, %ebx) */
+3:
+ movl %ebx,%ecx
+
+#if defined(I586_CPU) && NNPX > 0
+ ALIGN_TEXT
+slow_copyout:
+#endif
+ shrl $2,%ecx
+ cld
+ rep
+ movsl
+ movb %bl,%cl
+ andb $3,%cl
+ rep
+ movsb
+
+done_copyout:
+ popl %ebx
+ popl %edi
+ popl %esi
+ xorl %eax,%eax
+ movl _curpcb,%edx
+ movl %eax,PCB_ONFAULT(%edx)
+ ret
+
+ ALIGN_TEXT
+copyout_fault:
+ popl %ebx
+ popl %edi
+ popl %esi
+ movl _curpcb,%edx
+ movl $0,PCB_ONFAULT(%edx)
+ movl $EFAULT,%eax
+ ret
+
+#if defined(I586_CPU) && NNPX > 0
+ENTRY(i586_copyout)
+ /*
+ * Duplicated from generic_copyout. Could be done a bit better.
+ */
+ movl _curpcb,%eax
+ movl $copyout_fault,PCB_ONFAULT(%eax)
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+ movl 16(%esp),%esi
+ movl 20(%esp),%edi
+ movl 24(%esp),%ebx
+ testl %ebx,%ebx /* anything to do? */
+ jz done_copyout
+
+ /*
+ * Check explicitly for non-user addresses. If 486 write protection
+ * is being used, this check is essential because we are in kernel
+ * mode so the h/w does not provide any protection against writing
+ * kernel addresses.
+ */
+
+ /*
+ * First, prevent address wrapping.
+ */
+ movl %edi,%eax
+ addl %ebx,%eax
+ jc copyout_fault
+/*
+ * XXX STOP USING VM_MAXUSER_ADDRESS.
+ * It is an end address, not a max, so every time it is used correctly it
+ * looks like there is an off by one error, and of course it caused an off
+ * by one error in several places.
+ */
+ cmpl $VM_MAXUSER_ADDRESS,%eax
+ ja copyout_fault
+
+ /* bcopy(%esi, %edi, %ebx) */
+3:
+ movl %ebx,%ecx
+ /*
+ * End of duplicated code.
+ */
+
+ cmpl $1024,%ecx
+ jb slow_copyout
+
+ pushl %ecx
+ call _fastmove
+ addl $4,%esp
+ jmp done_copyout
+#endif /* I586_CPU && NNPX > 0 */
+
+/* copyin(from_user, to_kernel, len) */
+ENTRY(copyin)
+ MEXITCOUNT
+ jmp *_copyin_vector
+
+ENTRY(generic_copyin)
+ movl _curpcb,%eax
+ movl $copyin_fault,PCB_ONFAULT(%eax)
+ pushl %esi
+ pushl %edi
+ movl 12(%esp),%esi /* caddr_t from */
+ movl 16(%esp),%edi /* caddr_t to */
+ movl 20(%esp),%ecx /* size_t len */
+
+ /*
+ * make sure address is valid
+ */
+ movl %esi,%edx
+ addl %ecx,%edx
+ jc copyin_fault
+ cmpl $VM_MAXUSER_ADDRESS,%edx
+ ja copyin_fault
+
+#if defined(I586_CPU) && NNPX > 0
+ ALIGN_TEXT
+slow_copyin:
+#endif
+ movb %cl,%al
+ shrl $2,%ecx /* copy longword-wise */
+ cld
+ rep
+ movsl
+ movb %al,%cl
+ andb $3,%cl /* copy remaining bytes */
+ rep
+ movsb
+
+#if defined(I586_CPU) && NNPX > 0
+ ALIGN_TEXT
+done_copyin:
+#endif
+ popl %edi
+ popl %esi
+ xorl %eax,%eax
+ movl _curpcb,%edx
+ movl %eax,PCB_ONFAULT(%edx)
+ ret
+
+ ALIGN_TEXT
+copyin_fault:
+ popl %edi
+ popl %esi
+ movl _curpcb,%edx
+ movl $0,PCB_ONFAULT(%edx)
+ movl $EFAULT,%eax
+ ret
+
+#if defined(I586_CPU) && NNPX > 0
+ENTRY(i586_copyin)
+ /*
+ * Duplicated from generic_copyin. Could be done a bit better.
+ */
+ movl _curpcb,%eax
+ movl $copyin_fault,PCB_ONFAULT(%eax)
+ pushl %esi
+ pushl %edi
+ movl 12(%esp),%esi /* caddr_t from */
+ movl 16(%esp),%edi /* caddr_t to */
+ movl 20(%esp),%ecx /* size_t len */
+
+ /*
+ * make sure address is valid
+ */
+ movl %esi,%edx
+ addl %ecx,%edx
+ jc copyin_fault
+ cmpl $VM_MAXUSER_ADDRESS,%edx
+ ja copyin_fault
+ /*
+ * End of duplicated code.
+ */
+
+ cmpl $1024,%ecx
+ jb slow_copyin
+
+ pushl %ebx /* XXX prepare for fastmove_fault */
+ pushl %ecx
+ call _fastmove
+ addl $8,%esp
+ jmp done_copyin
+#endif /* I586_CPU && NNPX > 0 */
+
+#if defined(I586_CPU) && NNPX > 0
+/* fastmove(src, dst, len)
+ src in %esi
+ dst in %edi
+ len in %ecx XXX changed to on stack for profiling
+ uses %eax and %edx for tmp. storage
+ */
+/* XXX use ENTRY() to get profiling. fastmove() is actually a non-entry. */
+ENTRY(fastmove)
+ pushl %ebp
+ movl %esp,%ebp
+ subl $PCB_SAVEFPU_SIZE+3*4,%esp
+
+ movl 8(%ebp),%ecx
+ cmpl $63,%ecx
+ jbe fastmove_tail
+
+ testl $7,%esi /* check if src addr is multiple of 8 */
+ jnz fastmove_tail
+
+ testl $7,%edi /* check if dst addr is multiple of 8 */
+ jnz fastmove_tail
+
+/* if (npxproc != NULL) { */
+ cmpl $0,_npxproc
+ je 6f
+/* fnsave(&curpcb->pcb_savefpu); */
+ movl _curpcb,%eax
+ fnsave PCB_SAVEFPU(%eax)
+/* npxproc = NULL; */
+ movl $0,_npxproc
+/* } */
+6:
+/* now we own the FPU. */
+
+/*
+ * The process' FP state is saved in the pcb, but if we get
+ * switched, the cpu_switch() will store our FP state in the
+ * pcb. It should be possible to avoid all the copying for
+ * this, e.g., by setting a flag to tell cpu_switch() to
+ * save the state somewhere else.
+ */
+/* tmp = curpcb->pcb_savefpu; */
+ movl %ecx,-12(%ebp)
+ movl %esi,-8(%ebp)
+ movl %edi,-4(%ebp)
+ movl %esp,%edi
+ movl _curpcb,%esi
+ addl $PCB_SAVEFPU,%esi
+ cld
+ movl $PCB_SAVEFPU_SIZE>>2,%ecx
+ rep
+ movsl
+ movl -12(%ebp),%ecx
+ movl -8(%ebp),%esi
+ movl -4(%ebp),%edi
+/* stop_emulating(); */
+ clts
+/* npxproc = curproc; */
+ movl _curproc,%eax
+ movl %eax,_npxproc
+ movl _curpcb,%eax
+ movl $fastmove_fault,PCB_ONFAULT(%eax)
+4:
+ movl %ecx,-12(%ebp)
+ cmpl $1792,%ecx
+ jbe 2f
+ movl $1792,%ecx
+2:
+ subl %ecx,-12(%ebp)
+ cmpl $256,%ecx
+ jb 5f
+ movl %ecx,-8(%ebp)
+ movl %esi,-4(%ebp)
+ ALIGN_TEXT
+3:
+ movl 0(%esi),%eax
+ movl 32(%esi),%eax
+ movl 64(%esi),%eax
+ movl 96(%esi),%eax
+ movl 128(%esi),%eax
+ movl 160(%esi),%eax
+ movl 192(%esi),%eax
+ movl 224(%esi),%eax
+ addl $256,%esi
+ subl $256,%ecx
+ cmpl $256,%ecx
+ jae 3b
+ movl -8(%ebp),%ecx
+ movl -4(%ebp),%esi
+5:
+ ALIGN_TEXT
+fastmove_loop:
+ fildq 0(%esi)
+ fildq 8(%esi)
+ fildq 16(%esi)
+ fildq 24(%esi)
+ fildq 32(%esi)
+ fildq 40(%esi)
+ fildq 48(%esi)
+ fildq 56(%esi)
+ fistpq 56(%edi)
+ fistpq 48(%edi)
+ fistpq 40(%edi)
+ fistpq 32(%edi)
+ fistpq 24(%edi)
+ fistpq 16(%edi)
+ fistpq 8(%edi)
+ fistpq 0(%edi)
+ addl $-64,%ecx
+ addl $64,%esi
+ addl $64,%edi
+ cmpl $63,%ecx
+ ja fastmove_loop
+ movl -12(%ebp),%eax
+ addl %eax,%ecx
+ cmpl $64,%ecx
+ jae 4b
+
+/* curpcb->pcb_savefpu = tmp; */
+ movl %ecx,-12(%ebp)
+ movl %esi,-8(%ebp)
+ movl %edi,-4(%ebp)
+ movl _curpcb,%edi
+ addl $PCB_SAVEFPU,%edi
+ movl %esp,%esi
+ cld
+ movl $PCB_SAVEFPU_SIZE>>2,%ecx
+ rep
+ movsl
+ movl -12(%ebp),%ecx
+ movl -8(%ebp),%esi
+ movl -4(%ebp),%edi
+
+/* start_emulating(); */
+ smsw %ax
+ orb $CR0_TS,%al
+ lmsw %ax
+/* npxproc = NULL; */
+ movl $0,_npxproc
+
+ ALIGN_TEXT
+fastmove_tail:
+ movl _curpcb,%eax
+ movl $fastmove_tail_fault,PCB_ONFAULT(%eax)
+
+ movb %cl,%al
+ shrl $2,%ecx /* copy longword-wise */
+ cld
+ rep
+ movsl
+ movb %al,%cl
+ andb $3,%cl /* copy remaining bytes */
+ rep
+ movsb
+
+ movl %ebp,%esp
+ popl %ebp
+ ret
+
+ ALIGN_TEXT
+fastmove_fault:
+ movl _curpcb,%edi
+ addl $PCB_SAVEFPU,%edi
+ movl %esp,%esi
+ cld
+ movl $PCB_SAVEFPU_SIZE>>2,%ecx
+ rep
+ movsl
+
+ smsw %ax
+ orb $CR0_TS,%al
+ lmsw %ax
+ movl $0,_npxproc
+
+fastmove_tail_fault:
+ movl %ebp,%esp
+ popl %ebp
+ addl $8,%esp
+ popl %ebx
+ popl %edi
+ popl %esi
+ movl _curpcb,%edx
+ movl $0,PCB_ONFAULT(%edx)
+ movl $EFAULT,%eax
+ ret
+#endif /* I586_CPU && NNPX > 0 */
+
+/*
+ * fu{byte,sword,word} : fetch a byte (sword, word) from user memory
+ */
+ENTRY(fuword)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx /* from */
+
+ cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address is valid */
+ ja fusufault
+
+ movl (%edx),%eax
+ movl $0,PCB_ONFAULT(%ecx)
+ ret
+
+/*
+ * These two routines are called from the profiling code, potentially
+ * at interrupt time. If they fail, that's okay, good things will
+ * happen later. Fail all the time for now - until the trap code is
+ * able to deal with this.
+ */
+ALTENTRY(suswintr)
+ENTRY(fuswintr)
+ movl $-1,%eax
+ ret
+
+ENTRY(fusword)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+
+ cmpl $VM_MAXUSER_ADDRESS-2,%edx
+ ja fusufault
+
+ movzwl (%edx),%eax
+ movl $0,PCB_ONFAULT(%ecx)
+ ret
+
+ENTRY(fubyte)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+
+ cmpl $VM_MAXUSER_ADDRESS-1,%edx
+ ja fusufault
+
+ movzbl (%edx),%eax
+ movl $0,PCB_ONFAULT(%ecx)
+ ret
+
+ ALIGN_TEXT
+fusufault:
+ movl _curpcb,%ecx
+ xorl %eax,%eax
+ movl %eax,PCB_ONFAULT(%ecx)
+ decl %eax
+ ret
+
+/*
+ * su{byte,sword,word}: write a byte (word, longword) to user memory
+ */
+ENTRY(suword)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+
+#if defined(I386_CPU)
+
+#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
+ cmpl $CPUCLASS_386,_cpu_class
+ jne 2f /* we only have to set the right segment selector */
+#endif /* I486_CPU || I586_CPU || I686_CPU */
+
+ /* XXX - page boundary crossing is still not handled */
+ movl %edx,%eax
+ shrl $IDXSHIFT,%edx
+ andb $0xfc,%dl
+
+ leal _PTmap(%edx),%ecx
+ shrl $IDXSHIFT,%ecx
+ andb $0xfc,%cl
+ testb $PG_V,_PTmap(%ecx) /* PTE page must be valid */
+ je 4f
+ movb _PTmap(%edx),%dl
+ andb $PG_V|PG_RW|PG_U,%dl /* page must be valid and user writable */
+ cmpb $PG_V|PG_RW|PG_U,%dl
+ je 1f
+
+4:
+ /* simulate a trap */
+ pushl %eax
+ call _trapwrite
+ popl %edx /* remove junk parameter from stack */
+ testl %eax,%eax
+ jnz fusufault
+1:
+ movl 4(%esp),%edx
+#endif
+
+2:
+ cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address validity */
+ ja fusufault
+
+ movl 8(%esp),%eax
+ movl %eax,(%edx)
+ xorl %eax,%eax
+ movl _curpcb,%ecx
+ movl %eax,PCB_ONFAULT(%ecx)
+ ret
+
+ENTRY(susword)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+
+#if defined(I386_CPU)
+
+#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
+ cmpl $CPUCLASS_386,_cpu_class
+ jne 2f
+#endif /* I486_CPU || I586_CPU || I686_CPU */
+
+ /* XXX - page boundary crossing is still not handled */
+ movl %edx,%eax
+ shrl $IDXSHIFT,%edx
+ andb $0xfc,%dl
+
+ leal _PTmap(%edx),%ecx
+ shrl $IDXSHIFT,%ecx
+ andb $0xfc,%cl
+ testb $PG_V,_PTmap(%ecx) /* PTE page must be valid */
+ je 4f
+ movb _PTmap(%edx),%dl
+ andb $PG_V|PG_RW|PG_U,%dl /* page must be valid and user writable */
+ cmpb $PG_V|PG_RW|PG_U,%dl
+ je 1f
+
+4:
+ /* simulate a trap */
+ pushl %eax
+ call _trapwrite
+ popl %edx /* remove junk parameter from stack */
+ testl %eax,%eax
+ jnz fusufault
+1:
+ movl 4(%esp),%edx
+#endif
+
+2:
+ cmpl $VM_MAXUSER_ADDRESS-2,%edx /* verify address validity */
+ ja fusufault
+
+ movw 8(%esp),%ax
+ movw %ax,(%edx)
+ xorl %eax,%eax
+ movl _curpcb,%ecx /* restore trashed register */
+ movl %eax,PCB_ONFAULT(%ecx)
+ ret
+
+ALTENTRY(suibyte)
+ENTRY(subyte)
+ movl _curpcb,%ecx
+ movl $fusufault,PCB_ONFAULT(%ecx)
+ movl 4(%esp),%edx
+
+#if defined(I386_CPU)
+
+#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
+ cmpl $CPUCLASS_386,_cpu_class
+ jne 2f
+#endif /* I486_CPU || I586_CPU || I686_CPU */
+
+ movl %edx,%eax
+ shrl $IDXSHIFT,%edx
+ andb $0xfc,%dl
+
+ leal _PTmap(%edx),%ecx
+ shrl $IDXSHIFT,%ecx
+ andb $0xfc,%cl
+ testb $PG_V,_PTmap(%ecx) /* PTE page must be valid */
+ je 4f
+ movb _PTmap(%edx),%dl
+ andb $PG_V|PG_RW|PG_U,%dl /* page must be valid and user writable */
+ cmpb $PG_V|PG_RW|PG_U,%dl
+ je 1f
+
+4:
+ /* simulate a trap */
+ pushl %eax
+ call _trapwrite
+ popl %edx /* remove junk parameter from stack */
+ testl %eax,%eax
+ jnz fusufault
+1:
+ movl 4(%esp),%edx
+#endif
+
+2:
+ cmpl $VM_MAXUSER_ADDRESS-1,%edx /* verify address validity */
+ ja fusufault
+
+ movb 8(%esp),%al
+ movb %al,(%edx)
+ xorl %eax,%eax
+ movl _curpcb,%ecx /* restore trashed register */
+ movl %eax,PCB_ONFAULT(%ecx)
+ ret
+
+/*
+ * copyinstr(from, to, maxlen, int *lencopied)
+ * copy a string from from to to, stop when a 0 character is reached.
+ * return ENAMETOOLONG if string is longer than maxlen, and
+ * EFAULT on protection violations. If lencopied is non-zero,
+ * return the actual length in *lencopied.
+ */
+ENTRY(copyinstr)
+ pushl %esi
+ pushl %edi
+ movl _curpcb,%ecx
+ movl $cpystrflt,PCB_ONFAULT(%ecx)
+
+ movl 12(%esp),%esi /* %esi = from */
+ movl 16(%esp),%edi /* %edi = to */
+ movl 20(%esp),%edx /* %edx = maxlen */
+
+ movl $VM_MAXUSER_ADDRESS,%eax
+
+ /* make sure 'from' is within bounds */
+ subl %esi,%eax
+ jbe cpystrflt
+
+ /* restrict maxlen to <= VM_MAXUSER_ADDRESS-from */
+ cmpl %edx,%eax
+ jae 1f
+ movl %eax,%edx
+ movl %eax,20(%esp)
+1:
+ incl %edx
+ cld
+
+2:
+ decl %edx
+ jz 3f
+
+ lodsb
+ stosb
+ orb %al,%al
+ jnz 2b
+
+ /* Success -- 0 byte reached */
+ decl %edx
+ xorl %eax,%eax
+ jmp cpystrflt_x
+3:
+ /* edx is zero - return ENAMETOOLONG or EFAULT */
+ cmpl $VM_MAXUSER_ADDRESS,%esi
+ jae cpystrflt
+4:
+ movl $ENAMETOOLONG,%eax
+ jmp cpystrflt_x
+
+cpystrflt:
+ movl $EFAULT,%eax
+
+cpystrflt_x:
+ /* set *lencopied and return %eax */
+ movl _curpcb,%ecx
+ movl $0,PCB_ONFAULT(%ecx)
+ movl 20(%esp),%ecx
+ subl %edx,%ecx
+ movl 24(%esp),%edx
+ testl %edx,%edx
+ jz 1f
+ movl %ecx,(%edx)
+1:
+ popl %edi
+ popl %esi
+ ret
+
+
+/*
+ * copystr(from, to, maxlen, int *lencopied)
+ */
+ENTRY(copystr)
+ pushl %esi
+ pushl %edi
+
+ movl 12(%esp),%esi /* %esi = from */
+ movl 16(%esp),%edi /* %edi = to */
+ movl 20(%esp),%edx /* %edx = maxlen */
+ incl %edx
+ cld
+1:
+ decl %edx
+ jz 4f
+ lodsb
+ stosb
+ orb %al,%al
+ jnz 1b
+
+ /* Success -- 0 byte reached */
+ decl %edx
+ xorl %eax,%eax
+ jmp 6f
+4:
+ /* edx is zero -- return ENAMETOOLONG */
+ movl $ENAMETOOLONG,%eax
+
+6:
+ /* set *lencopied and return %eax */
+ movl 20(%esp),%ecx
+ subl %edx,%ecx
+ movl 24(%esp),%edx
+ testl %edx,%edx
+ jz 7f
+ movl %ecx,(%edx)
+7:
+ popl %edi
+ popl %esi
+ ret
+
+ENTRY(bcmp)
+ pushl %edi
+ pushl %esi
+ movl 12(%esp),%edi
+ movl 16(%esp),%esi
+ movl 20(%esp),%edx
+ xorl %eax,%eax
+
+ movl %edx,%ecx
+ shrl $2,%ecx
+ cld /* compare forwards */
+ repe
+ cmpsl
+ jne 1f
+
+ movl %edx,%ecx
+ andl $3,%ecx
+ repe
+ cmpsb
+ je 2f
+1:
+ incl %eax
+2:
+ popl %esi
+ popl %edi
+ ret
+
+
+/*
+ * Handling of special 386 registers and descriptor tables etc
+ */
+/* void lgdt(struct region_descriptor *rdp); */
+ENTRY(lgdt)
+ /* reload the descriptor table */
+ movl 4(%esp),%eax
+ lgdt (%eax)
+
+ /* flush the prefetch q */
+ jmp 1f
+ nop
+1:
+ /* reload "stale" selectors */
+ movl $KDSEL,%eax
+ movl %ax,%ds
+ movl %ax,%es
+ movl %ax,%ss
+
+ /* reload code selector by turning return into intersegmental return */
+ movl (%esp),%eax
+ pushl %eax
+# movl $KCSEL,4(%esp)
+ movl $8,4(%esp)
+ lret
+
+/*
+ * void lidt(struct region_descriptor *rdp);
+ */
+ENTRY(lidt)
+ movl 4(%esp),%eax
+ lidt (%eax)
+ ret
+
+/*
+ * void lldt(u_short sel)
+ */
+ENTRY(lldt)
+ lldt 4(%esp)
+ ret
+
+/*
+ * void ltr(u_short sel)
+ */
+ENTRY(ltr)
+ ltr 4(%esp)
+ ret
+
+/* ssdtosd(*ssdp,*sdp) */
+ENTRY(ssdtosd)
+ pushl %ebx
+ movl 8(%esp),%ecx
+ movl 8(%ecx),%ebx
+ shll $16,%ebx
+ movl (%ecx),%edx
+ roll $16,%edx
+ movb %dh,%bl
+ movb %dl,%bh
+ rorl $8,%ebx
+ movl 4(%ecx),%eax
+ movw %ax,%dx
+ andl $0xf0000,%eax
+ orl %eax,%ebx
+ movl 12(%esp),%ecx
+ movl %edx,(%ecx)
+ movl %ebx,4(%ecx)
+ popl %ebx
+ ret
+
+/* load_cr0(cr0) */
+ENTRY(load_cr0)
+ movl 4(%esp),%eax
+ movl %eax,%cr0
+ ret
+
+/* rcr0() */
+ENTRY(rcr0)
+ movl %cr0,%eax
+ ret
+
+/* rcr3() */
+ENTRY(rcr3)
+ movl %cr3,%eax
+ ret
+
+/* void load_cr3(caddr_t cr3) */
+ENTRY(load_cr3)
+ movl 4(%esp),%eax
+ movl %eax,%cr3
+ ret
+
+
+/*****************************************************************************/
+/* setjump, longjump */
+/*****************************************************************************/
+
+ENTRY(setjmp)
+ movl 4(%esp),%eax
+ movl %ebx,(%eax) /* save ebx */
+ movl %esp,4(%eax) /* save esp */
+ movl %ebp,8(%eax) /* save ebp */
+ movl %esi,12(%eax) /* save esi */
+ movl %edi,16(%eax) /* save edi */
+ movl (%esp),%edx /* get rta */
+ movl %edx,20(%eax) /* save eip */
+ xorl %eax,%eax /* return(0); */
+ ret
+
+ENTRY(longjmp)
+ movl 4(%esp),%eax
+ movl (%eax),%ebx /* restore ebx */
+ movl 4(%eax),%esp /* restore esp */
+ movl 8(%eax),%ebp /* restore ebp */
+ movl 12(%eax),%esi /* restore esi */
+ movl 16(%eax),%edi /* restore edi */
+ movl 20(%eax),%edx /* get rta */
+ movl %edx,(%esp) /* put in return frame */
+ xorl %eax,%eax /* return(1); */
+ incl %eax
+ ret
+
+/*
+ * Here for doing BB-profiling (gcc -a).
+ * We rely on the "bbset" instead, but need a dummy function.
+ */
+NON_GPROF_ENTRY(__bb_init_func)
+ movl 4(%esp),%eax
+ movl $1,(%eax)
+ .byte 0xc3 /* avoid macro for `ret' */
Index: speedtst/speed.c
===================================================================
--- speedtst/speed.c (nonexistent)
+++ speedtst/speed.c (revision 174)
@@ -0,0 +1,292 @@
+#include
+#include
+#include
+
+#ifdef TEST_FOR_X
+#include
+#else
+#define MWINCLUDECOLORS
+#include
+#endif
+
+#define NUM_POINTS 80
+
+time_t start_time, end_time;
+
+void start_timer()
+{
+ time(&start_time);
+}
+
+void end_timer()
+{
+ time(&end_time);
+ printf("start=%lu, end=%lu, time=%lu\n",
+ start_time, end_time, end_time-start_time);
+}
+
+int main()
+{
+#ifdef TEST_FOR_X
+ Display *display;
+ Window window;
+ GC gc;
+ XGCValues gcValues;
+ Colormap colormap;
+ Pixmap src_pixmap;
+ unsigned long fgColor, bgColor;
+ int screenNum;
+ XPoint points[NUM_POINTS];
+#else
+ GR_WINDOW_ID window;
+ GR_WINDOW_ID src_pixmap;
+ unsigned char* src_pixmap_buf[320*240*2];
+ GR_GC_ID gc;
+ GR_POINT points[NUM_POINTS];
+#endif
+
+ int c, c1, count=4500;
+ int x, y, x1, y1, x2, y2;
+
+#ifdef TEST_FOR_X
+ if(!(display=XOpenDisplay(""))) {
+ printf("Cannot connect to X.\n");
+ }
+ screenNum = DefaultScreen(display);
+ colormap = DefaultColormap(display, screenNum);
+
+ bgColor = BlackPixel(display, screenNum);
+ fgColor = WhitePixel(display, screenNum);
+ window = XCreateSimpleWindow(display, RootWindow(display, screenNum),
+ 0, 0 , 639, 479, 0,
+ fgColor, bgColor);
+ src_pixmap = XCreatePixmap(display, window, 320, 240, 16);
+ XMapRaised(display, window);
+ gcValues.background = bgColor;
+ gcValues.foreground = fgColor;
+ gcValues.line_width = 1;
+ gcValues.line_style = LineSolid;
+ gcValues.fill_style = FillSolid;
+ gcValues.fill_rule = WindingRule;
+ gcValues.arc_mode = ArcPieSlice;
+ gc = XCreateGC(display, window,
+ GCForeground | GCBackground | GCLineWidth | GCLineStyle |
+ GCFillStyle,
+ &gcValues);
+
+#else
+ GrOpen();
+ window = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, 639, 479, 0, BLACK, BLUE);
+ src_pixmap = GrNewPixmap(640, 480, src_pixmap_buf);
+ GrMapWindow(window);
+ gc = GrNewGC();
+ GrSetGCForeground(gc, WHITE);
+ GrSetGCBackground(gc, BLACK);
+ GrSetGCMode(gc, GR_MODE_COPY);
+#endif
+
+
+
+
+
+ // Horizontal Line
+ ////////////////////////////////////////////////
+ printf("Horizontal Line(XDrawLine)\n");
+ start_timer();
+ for(c=0; c
Index: turboc/MWIN-TCW.PRJ
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: turboc/MWIN-TCW.PRJ
===================================================================
--- turboc/MWIN-TCW.PRJ (nonexistent)
+++ turboc/MWIN-TCW.PRJ (revision 174)
turboc/MWIN-TCW.PRJ
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: turboc/readme.tc
===================================================================
--- turboc/readme.tc (nonexistent)
+++ turboc/readme.tc (revision 174)
@@ -0,0 +1,102 @@
+For compile Microwindows for DOS & TURBO C
+you should have the following:
+====================================================
+1. Microwin 0.87 - microwindows.censoft.com
+2. Turbo C++ ver. 1.0 or Borland C ver. 3.1
+
+
+You should do the following:
+----------------------------
+
+- copy mwin-tcn.prj to microwin\src\
+- copy mwin-tcw.prj to microwin\src\
+
+- run tc or bc IDE
+- load the project
+
+
+You should check the next:
+-------------------------
+
+- correct paths
+- settings defines in :
+ options | compiler | code generation - defines :
+
+ ERASEMOVE=1;
+ MSDOS=1;
+ DOS_TURBOC=1;
+
+
+MAKE !
+====================================================
+
+- mwin-pcw.prj = mwin demo
+- mwin-pcn.prj = nanox demo
+
+For nanox add next defines:
+ NONETWORK=1;
+ SCREEN_PIXTYPE=PF_PALETTE;
+
+
+! NOT all demos have been tested.
+====================================================
+
+The project for mwin demo must have next files:
+
+\DEMOS\MWIN\DEMO.C
+\DRIVERS\GENFONT.C
+\DRIVERS\KBD_TC.C
+\DRIVERS\MOU_DOS.C
+\DRIVERS\SCR_TC.C
+\FONTS\ROM8X16.C
+\FONTS\ROM8X8.C
+\FONTS\WINFRE~1.C
+\FONTS\WINFRE~2.C
+\ENGINE\DEVCLIP.C
+\ENGINE\DEVDRAW.C
+\ENGINE\DEVKBD.C
+\ENGINE\DEVMOUSE.C
+\ENGINE\DEVPAL1.C
+\ENGINE\DEVPAL2.C
+\ENGINE\DEVPAL4.C
+\MWIN\WINCLIP.C
+\MWIN\WINDEFW.C
+\MWIN\WINEVENT.C
+\MWIN\WINEXPOS.C
+\MWIN\WINMAIN.C
+\MWIN\WINUSER.C
+\MWIN\WINGDI.C
+\MWIN\LIST.C
+\MWIN\WINLIB\BUTTON.C
+\MWIN\WINLIB\DRAW3D.C
+\MWIN\WINLIB\FASTFILL.C
+\MWIN\WINLIB\GRAPH3D.C
+\MWIN\WINLIB\INSETR.C
+\MWIN\WINLIB\PTINSID.C
+\MWIN\BMP\CS1.C
+
+The project for nanox demo must have next files:
+
+\DEMOS\NANOX\DEMO.C
+\DRIVERS\GENFONT.C
+\DRIVERS\KBD_TC.C
+\DRIVERS\MOU_DOS.C
+\DRIVERS\SCR_TC.C
+\FONTS\ROM8X16.C
+\FONTS\ROM8X8.C
+\FONTS\WINFRE~1.C
+\ENGINE\DEVCLIP.C
+\ENGINE\DEVDRAW.C
+\ENGINE\DEVKBD.C
+\ENGINE\DEVMOUSE.C
+\ENGINE\DEVPAL1.C
+\ENGINE\DEVPAL2.C
+\ENGINE\DEVPAL4.C
+\NANOX\SRVEVENT.C
+\NANOX\SRVFUNC.C
+\NANOX\SRVMAIN.C
+\NANOX\SRVUTIL.C
+\NANOX\STUBS.C
+
+====================================================
+Victor Rogachev
Index: turboc/MWIN-TCN.PRJ
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: turboc/MWIN-TCN.PRJ
===================================================================
--- turboc/MWIN-TCN.PRJ (nonexistent)
+++ turboc/MWIN-TCN.PRJ (revision 174)
turboc/MWIN-TCN.PRJ
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property