Subversion Repositories pentevo

Rev

Rev 1134 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

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