Subversion Repositories pentevo

Rev

Rev 716 | Blame | Last modification | View Log | Download | RSS feed

  1. #include "std.h"
  2.  
  3. #include "emul.h"
  4. #include "vars.h"
  5. #include "snapshot.h"
  6. #include "init.h"
  7.  
  8. #include "util.h"
  9.  
  10. static void cpuid(unsigned CpuInfo[4], unsigned _eax)
  11. {
  12. #ifdef _MSC_VER
  13.    __cpuid((int *)CpuInfo, _eax);
  14. #endif
  15.  
  16. #ifdef __GNUC__
  17. #ifdef __clang__
  18.    __cpuid((int *)CpuInfo, _eax);
  19. #else
  20.    __cpuid(_eax, CpuInfo[0], CpuInfo[1], CpuInfo[2], CpuInfo[3]);
  21. #endif // __clang__
  22. #endif
  23. }
  24.  
  25. void fillCpuString(char dst[49])
  26. {
  27.    dst[0] = dst[12] = dst[48] = 0;
  28.    unsigned CpuInfo[4];
  29.    unsigned *d = (unsigned *)dst;
  30.  
  31.    cpuid(CpuInfo, 0x80000000);
  32.    if(CpuInfo[0] < 0x80000004)
  33.    {
  34.        cpuid(CpuInfo, 0);
  35.        d[0] = CpuInfo[1];
  36.        d[1] = CpuInfo[3];
  37.        d[2] = CpuInfo[2];
  38.        return;
  39.    }
  40.  
  41.    cpuid(CpuInfo, 0x80000002);
  42.    d[0] = CpuInfo[0];
  43.    d[1] = CpuInfo[1];
  44.    d[2] = CpuInfo[2];
  45.    d[3] = CpuInfo[3];
  46.  
  47.    cpuid(CpuInfo, 0x80000003);
  48.    d[4] = CpuInfo[0];
  49.    d[5] = CpuInfo[1];
  50.    d[6] = CpuInfo[2];
  51.    d[7] = CpuInfo[3];
  52.  
  53.    cpuid(CpuInfo, 0x80000004);
  54.    d[ 8] = CpuInfo[0];
  55.    d[ 9] = CpuInfo[1];
  56.    d[10] = CpuInfo[2];
  57.    d[11] = CpuInfo[3];
  58. }
  59.  
  60. unsigned cpuid(unsigned _eax, int ext)
  61. {
  62.    unsigned CpuInfo[4];
  63.  
  64.    cpuid(CpuInfo, _eax);
  65.  
  66.    return ext ? CpuInfo[3] : CpuInfo[0];
  67. }
  68.  
  69. unsigned __int64 GetCPUFrequency()
  70. {
  71.    LARGE_INTEGER Frequency;
  72.    LARGE_INTEGER Start;
  73.    LARGE_INTEGER Stop;
  74.    unsigned long long c1, c2;
  75.  
  76.    QueryPerformanceFrequency(&Frequency);
  77.    LONGLONG t = Frequency.QuadPart >> 3;
  78.    c1 = rdtsc();
  79.    QueryPerformanceCounter(&Start);
  80.    do
  81.    {
  82.        QueryPerformanceCounter(&Stop);
  83.    } while((Stop.QuadPart - Start.QuadPart) < t);
  84.    c2 = rdtsc();
  85.  
  86.    return (c2 - c1) << 3;
  87. }
  88.  
  89. void trim(char *dst)
  90. {
  91.    unsigned i = strlen(dst);
  92.    // trim right spaces
  93.    while (i && isspace(u8(dst[i-1]))) i--;
  94.    dst[i] = 0;
  95.    // trim left spaces
  96.    for (i = 0; isspace(u8(dst[i])); i++);
  97.    strcpy(dst, dst+i);
  98. }
  99.  
  100.  
  101. const char clrline[] = "\r\t\t\t\t\t\t\t\t\t       \r";
  102.  
  103. #define savetab(x) {FILE *ff=fopen("tab","wb");fwrite(x,sizeof(x),1,ff);fclose(ff);}
  104.  
  105. #define tohex(a) ((a) < 10 ? (a)+'0' : (a)-10+'A')
  106.  
  107. const char nop = 0;
  108. const char * const nil = &nop;
  109.  
  110. int ishex(char c)
  111. {
  112.    return (isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f'));
  113. }
  114.  
  115. unsigned char hex(char p)
  116. {
  117.    p = tolower(p);
  118.    return (p < 'a') ? p-'0' : p-'a'+10;
  119. }
  120.  
  121. unsigned char hex(const char *p)
  122. {
  123.    return 0x10*hex(p[0]) + hex(p[1]);
  124. }
  125.  
  126. unsigned process_msgs()
  127. {
  128.    MSG msg;
  129.    unsigned key = 0;
  130.  
  131.    while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  132.    {
  133. /*
  134.       if (msg.message == WM_NCLBUTTONDOWN)
  135.           continue;
  136. */
  137.       // mouse messages must be processed further
  138.       if (msg.message == WM_LBUTTONDOWN)
  139.       {
  140.           mousepos = msg.lParam;
  141.           key = VK_LMB;
  142.       }
  143.       if (msg.message == WM_RBUTTONDOWN)
  144.       {
  145.           mousepos = msg.lParam | 0x80000000;
  146.           key = VK_RMB;
  147.       }
  148.       if (msg.message == WM_MBUTTONDOWN)
  149.       {
  150.           mousepos = msg.lParam | 0x80000000;
  151.           key = VK_MMB;
  152.       }
  153.  
  154.       if (msg.message == WM_MOUSEWHEEL) // [vv] Process mouse whell only in client area
  155.       {
  156.           POINT Pos = { GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam) };
  157.  
  158.           RECT ClientRect;
  159.           GetClientRect(msg.hwnd, &ClientRect);
  160.           MapWindowPoints(msg.hwnd, HWND_DESKTOP, (LPPOINT)&ClientRect, 2);
  161.  
  162.           if(PtInRect(&ClientRect, Pos))
  163.               key = GET_WHEEL_DELTA_WPARAM(msg.wParam) < 0 ? VK_MWD : VK_MWU;
  164.       }
  165.  
  166.       // WM_KEYDOWN and WM_SYSKEYDOWN must not be dispatched,
  167.       // bcoz window will be closed on alt-f4
  168.       if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN)
  169.       {
  170.          if (conf.atm.xt_kbd)
  171.              input.atm51.setkey(msg.lParam >> 16, 1);
  172.          switch (( msg.lParam>>16)&0x1FF)
  173.          {
  174.             case 0x02a: kbdpcEX[0]=(kbdpcEX[0]^0x01)|0x80; break;
  175.             case 0x036: kbdpcEX[1]=(kbdpcEX[1]^0x01)|0x80; break;
  176.             case 0x01d: kbdpcEX[2]=(kbdpcEX[2]^0x01)|0x80; break;
  177.             case 0x11d: kbdpcEX[3]=(kbdpcEX[3]^0x01)|0x80; break;
  178.             case 0x038: kbdpcEX[4]=(kbdpcEX[4]^0x01)|0x80; break;
  179.             case 0x138: kbdpcEX[5]=(kbdpcEX[5]^0x01)|0x80; break;
  180.          } //Dexus
  181. //         printf("%s, WM_KEYDOWN, WM_SYSKEYDOWN\n", __FUNCTION__);
  182.          key = msg.wParam;
  183.       }
  184.       else if (msg.message == WM_KEYUP || msg.message == WM_SYSKEYUP)
  185.       {
  186.          if (conf.atm.xt_kbd) input.atm51.setkey(msg.lParam >> 16, 0);
  187.          switch (( msg.lParam>>16)&0x1FF)
  188.          {
  189.             case 0x02a: kbdpcEX[0]&=0x01; kbdpcEX[1]&=0x01; break;
  190.             case 0x036: kbdpcEX[0]&=0x01; kbdpcEX[1]&=0x01; break;
  191.             case 0x01d: kbdpcEX[2]&=0x01; break;
  192.             case 0x11d: kbdpcEX[3]&=0x01; break;
  193.             case 0x038: kbdpcEX[4]&=0x01; break;
  194.             case 0x138: kbdpcEX[5]&=0x01; break;
  195.          } //Dexus
  196.  
  197. //         printf("%s, WM_KEYUP, WM_SYSKEYUP\n", __FUNCTION__);
  198. //         DispatchMessage(&msg); //Dexus
  199.       }
  200.  
  201.       if(!((WM_KEYFIRST <= msg.message) && (msg.message <= WM_KEYLAST)) ||
  202.           ((WM_MOUSEFIRST <= msg.message) && (msg.message <= WM_MOUSELAST)))
  203.          DispatchMessage(&msg);
  204.    }
  205.    return key;
  206. }
  207.  
  208. void eat() // eat messages
  209. {
  210.    Sleep(20);
  211.    while (process_msgs()) Sleep(10);
  212. }
  213.  
  214. bool dispatch_more(action *table)
  215. {
  216.    if (!table)
  217.        return false;
  218.  
  219.    u8 tmp = kbdpc[0];
  220.    kbdpc[0] = 0x80; // nil button is always pressed
  221.  
  222. //   __debugbreak();
  223.    while (table->name)
  224.    {
  225. //      printf("%02X|%02X|%02X|%02X\n", table->k1, table->k2, table->k3, table->k4);
  226.       unsigned k[4] = { table->k1, table->k2, table->k3, table->k4 };
  227.       unsigned b[4];
  228.  
  229.       for(unsigned i =0; i< 4; i++)
  230.       {
  231.           switch(k[i])
  232.           {
  233.           case DIK_MENU:
  234.               b[i] = kbdpc[DIK_LMENU] | kbdpc[DIK_RMENU]; // Alt
  235.           break;
  236.           case DIK_CONTROL:
  237.               b[i] = kbdpc[DIK_LCONTROL] | kbdpc[DIK_RCONTROL];
  238.           break;
  239.           case DIK_SHIFT:
  240.               b[i] = kbdpc[DIK_LSHIFT] | kbdpc[DIK_RSHIFT];
  241.           break;
  242.           default:
  243.               b[i] = kbdpc[k[i]];
  244.           }
  245.       }
  246.  
  247.       if (b[0] & b[1] & b[2] & b[3] & 0x80)
  248.       {
  249.          table->func();
  250.          kbdpc[0] = tmp;
  251.          return true;
  252.       }
  253.       table++;
  254.    }
  255.  
  256.    kbdpc[0] = tmp;
  257.    return false;
  258. }
  259.  
  260. bool dispatch(action *table)
  261. {
  262.    if (*droppedFile)
  263.    {
  264.        trd_toload = DefaultDrive;
  265.        loadsnap(droppedFile);
  266.        *droppedFile = 0;
  267.    }
  268.    if(!input.readdevices())
  269.        return false;
  270.  
  271.    dispatch_more(table);
  272.    return true;
  273. }
  274.  
  275. bool wcmatch(char *string, char *wc)
  276. {
  277.    for (;;wc++, string++) {
  278.       if (!*string && !*wc) return 1;
  279.       if (*wc == '?') { if (*string) continue; else return 0; }
  280.       if (*wc == '*') {
  281.          for (wc++; *string; string++)
  282.             if (wcmatch(string, wc)) return 1;
  283.          return 0;
  284.       }
  285.       if (tolower(*string) != tolower(*wc)) return 0;
  286.    }
  287. }
  288.  
  289. void dump1(BYTE *p, unsigned sz)
  290. {
  291.    while (sz) {
  292.       printf("\t");
  293.       unsigned chunk = (sz > 16)? 16 : sz;
  294.       unsigned i; //Alone Coder 0.36.7
  295.       for (/*unsigned*/ i = 0; i < chunk; i++) printf("%02X ", p[i]);
  296.       for (; i < 16; i++) printf("   ");
  297.       for (i = 0; i < chunk; i++) printf("%c", (p[i] < 0x20)? '.' : p[i]);
  298.       printf("\n");
  299.       sz -= chunk, p += chunk;
  300.    }
  301.    printf("\n");
  302. }
  303.  
  304. void color(int ink)
  305. {
  306.    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), ink);
  307. }
  308.  
  309. void err_win32(DWORD errcode)
  310. {
  311.    if (errcode == 0xFFFFFFFF) errcode = GetLastError();
  312.  
  313.    char msg[512];
  314.    if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, errcode,
  315.                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  316.                   msg, sizeof(msg), 0)) *msg = 0;
  317.  
  318.    trim(msg); CharToOem(msg, msg);
  319.  
  320.    color();
  321.    printf((*msg)? "win32 error message: " : "win32 error code: ");
  322.    color(CONSCLR_ERRCODE);
  323.    if (*msg) printf("%s\n", msg); else printf("%04lX\n", errcode);
  324.    color();
  325. }
  326.  
  327. void errmsg(const char *err, const char *str)
  328. {
  329.    color();
  330.    printf("error: ");
  331.    color(CONSCLR_ERROR);
  332.    printf(err, str);
  333.    color();
  334.    printf("\n");
  335.  
  336. #ifdef _DEBUG
  337.    OutputDebugString(err);
  338.    OutputDebugString(str);
  339.    OutputDebugString("\n");
  340. #endif
  341. }
  342.  
  343. void err_printf(const char *format, ...)
  344. {
  345.    va_list args;
  346.    va_start(args, format);
  347.    color();
  348.    printf("error: ");
  349.    color(CONSCLR_ERROR);
  350.    vprintf(format, args);
  351.    color();
  352.    printf("\n");
  353.    va_end(args);
  354. }
  355.  
  356. void __declspec(noreturn) errexit(const char *err, const char *str)
  357. {
  358.    errmsg(err, str);
  359.    exit();
  360. }
  361.  
  362.  
  363. extern "C" void * _ReturnAddress(void);
  364.  
  365. #ifndef __INTEL_COMPILER
  366. #pragma intrinsic(_ReturnAddress)
  367. #pragma intrinsic(_byteswap_ulong)
  368. #pragma intrinsic(_byteswap_ushort)
  369. #endif
  370.