OpenCores
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.