Subversion Repositories pentevo

Rev

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