Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
716 lvd 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