Subversion Repositories pentevo

Rev

Rev 1138 | Details | Compare with Previous | 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 "font.h"
6
#include "font16.h"
7
#include "gs.h"
8
#include "tape.h"
9
#include "draw.h"
10
#include "debug.h"
11
#include "dbgbpx.h"
12
#include "memory.h"
784 DimkaM 13
#include "leds.h"
716 lvd 14
 
15
#include "util.h"
16
 
784 DimkaM 17
static unsigned pitch;
716 lvd 18
 
784 DimkaM 19
void text_i(unsigned char *dst, const char *text, unsigned char ink, unsigned off)
716 lvd 20
{
784 DimkaM 21
   ink &= 0x0F;
22
   for (const u8 *x = (const u8*)text; *x; x++) {
716 lvd 23
      unsigned char *d0 = dst;
24
      for (unsigned y = 0; y < 8; y++) {
25
         unsigned char byte = font[(*x)*8+y];
26
         d0[0] = (byte >> off) + (d0[0] & ~(0xFC >> off));
27
         d0[1] = (d0[1] & 0xF0) + ink;
28
         if (off > 2) {
784 DimkaM 29
            d0[2] = u8((byte << (8-off)) + (d0[2] & ~(0xFC << (8-off))));
716 lvd 30
            d0[3] = (d0[3] & 0xF0) + ink;
31
         }
32
         d0 += pitch;
33
      }
784 DimkaM 34
      off += 6;
35
      if(off & 8)
36
      {
37
          off -= 8;
38
          dst += 2;
39
      }
716 lvd 40
   }
41
}
42
 
43
static void text_16(unsigned char *dst, const char *text, unsigned char attr)
44
{
784 DimkaM 45
    for(; *text; text++, dst += 2)
46
    {
47
        for(unsigned y = 0; y < 16; y++)
48
        {
49
            dst[y*pitch] = font16[16 * *(const u8*)text + y];
50
            dst[y*pitch + 1] = attr;
51
        }
52
    }
716 lvd 53
}
54
 
784 DimkaM 55
static unsigned char *aypos;
56
static void paint_led(unsigned level, unsigned char at)
716 lvd 57
{
58
   if (level) {
784 DimkaM 59
       if(level > 15)
60
       {
61
           level = 15; at = 0x0E;
62
       }
716 lvd 63
      unsigned mask = (0xFFFF0000 >> level) & 0xFFFF;
784 DimkaM 64
      aypos[0] = u8(mask >> 8);
716 lvd 65
      aypos[2] = (unsigned char)mask;
784 DimkaM 66
      aypos[1] = (aypos[1] & 0xF0) + at;
67
      aypos[3] = (aypos[3] & 0xF0) + at;
716 lvd 68
   }
69
   aypos += pitch;
70
}
71
 
784 DimkaM 72
static void ay_led()
716 lvd 73
{
74
   aypos = temp.led.ay;
75
   unsigned char sum=0;
76
 
77
   int max_ay = (conf.sound.ay_scheme > AY_SCHEME_PSEUDO)? 2 : 1;
78
   for (int n_ay = 0; n_ay < max_ay; n_ay++) {
784 DimkaM 79
      for (unsigned i = 0; i < 3; i++) {
716 lvd 80
         unsigned char r_mix = ay[n_ay].get_reg(7);
81
         unsigned char tone = (r_mix >> i) & 1,
82
                       noise = (r_mix >> (i+3)) & 1;
83
         unsigned char c1 = 0, c2 = 0;
84
         unsigned char v = ay[n_ay].get_reg(i+8);
85
         if (!tone) c1 = c2 = 0x0F;
86
         if (!noise) c2 = 0x0E;
87
         if (v & 0x10) {
88
            unsigned r_envT = ay[n_ay].get_reg(11) + 0x100*ay[n_ay].get_reg(12);
89
            if (r_envT < 0x400) {
90
               v = (3-(r_envT>>3)) & 0x0F;
91
               if (!v) v = 6;
784 DimkaM 92
            } else v = u8(ay[n_ay].get_env()/2);
716 lvd 93
            c1 = 0x0C;
94
         } else v &= 0x0F;
95
         if (!c1) c1 = c2;
96
         if (!c2) c2 = c1;
97
         if (!c1) v = 0;
98
         sum |= v;
99
         paint_led(v, c1);
100
         paint_led(v, c2);
101
         paint_led(0, 0);
102
      }
103
   }
104
 
105
   const unsigned FMvols[]={4,9,15,23,35,48,70,105,140,195,243,335,452,608,761,1023};
106
   #define _cBlue 0x09
107
   #define _cRed 0x0a
108
   #define _cPurp 0x0b
109
   #define _cGreen 0x0c
110
   #define _cCyan 0x0d
111
   #define _cYell 0x0e
112
   #define _cWhite 0x0f
113
 
784 DimkaM 114
   const u8 FMalg1[]={
716 lvd 115
   _cBlue , _cPurp , _cGreen, _cWhite,
116
   _cPurp , _cPurp , _cGreen, _cWhite,
117
   _cGreen, _cPurp , _cGreen, _cWhite,
118
   _cPurp , _cGreen, _cGreen, _cWhite,
119
 
120
   _cGreen, _cWhite, _cGreen, _cWhite,
121
   _cPurp , _cWhite, _cWhite, _cWhite,
122
   _cGreen, _cWhite, _cWhite, _cWhite,
123
   _cWhite, _cWhite, _cWhite, _cWhite
124
   };
125
 
784 DimkaM 126
   const u8 FMalg2[]={
716 lvd 127
   _cBlue , _cPurp , _cGreen, _cYell ,
128
   _cPurp , _cPurp , _cGreen, _cYell ,
129
   _cGreen, _cPurp , _cGreen, _cYell ,
130
   _cPurp , _cGreen, _cGreen, _cYell ,
131
 
132
   _cGreen, _cYell , _cGreen, _cYell ,
133
   _cPurp , _cYell , _cYell , _cYell ,
134
   _cGreen, _cYell , _cYell , _cYell ,
135
   _cYell , _cYell , _cYell , _cYell
136
   };
137
 
138
   const int FMslots[]={0,2,1,3};
139
/*
140
   const int FMalg1[]={
141
   _cPurp , _cGreen, _cCyan , _cWhite,
142
   _cPurp , _cPurp , _cGreen, _cWhite,
143
   _cGreen, _cPurp , _cCyan , _cWhite,
144
   _cPurp , _cCyan , _cGreen, _cWhite,
145
 
146
   _cPurp , _cWhite, _cGreen, _cWhite,
147
   _cPurp , _cWhite, _cWhite, _cWhite,
148
   _cGreen, _cWhite, _cWhite, _cWhite,
149
   _cWhite, _cWhite, _cWhite, _cWhite
150
   };
151
 
152
   const int FMalg2[]={
153
   _cPurp , _cGreen, _cCyan , _cYell ,
154
   _cPurp , _cPurp , _cGreen, _cYell ,
155
   _cGreen, _cPurp , _cCyan , _cYell ,
156
   _cPurp , _cCyan , _cGreen, _cYell ,
157
 
158
   _cPurp , _cYell , _cGreen, _cYell ,
159
   _cPurp , _cYell , _cYell , _cYell ,
160
   _cGreen, _cYell , _cYell , _cYell ,
161
   _cYell , _cYell , _cYell , _cYell
162
   };
163
*/
164
   if ( conf.sound.ay_chip == SNDCHIP::CHIP_YM2203 ) {
165
      for (int ayN = 0; ayN < max_ay; ayN++) {
166
         for (int i = 0; i < 3; i++) {
167
            for (int j = 0; j < 4; j++) {
168
               unsigned v=ay[ayN].Chip2203->CH[i].SLOT[j].vol_out;
169
               if (v>1023) v=1023;
784 DimkaM 170
               unsigned c; //Alone Coder 0.36.7
716 lvd 171
               for (/*int*/ c=0;c<16;c++)
172
                  if (FMvols[c]>=v) break;
173
               if ( (i == 2) && (((ay[ayN].Chip2203->OPN.ST.mode) & 0xc0) == 0x40) )
174
                  paint_led(15-c, FMalg2[ay[ayN].Chip2203->CH[i].ALGO * 4 + FMslots[j]]);
175
               else
176
                  paint_led(15-c, FMalg1[ay[ayN].Chip2203->CH[i].ALGO * 4 + FMslots[j]]);
177
            }
178
         paint_led(0, 0);
179
         }
180
      }
181
   } //Dexus
182
 
183
   #ifdef MOD_GS
184
   if (sum || !conf.gs_type) return; // else show GS indicators
185
   aypos = temp.led.ay; // reset y-pos, if nothing above
186
   for (unsigned ch = 0; ch < 8; ch++) {
187
      unsigned v = gsleds[ch].level, a = gsleds[ch].attrib;
784 DimkaM 188
      paint_led(v, u8(a));
189
      paint_led(v, u8(a));
716 lvd 190
      paint_led(0, 0);
800 DimkaM 191
 
192
#if 0
193
      printf("{%2u}", v);
194
      for(unsigned i = 0; i < v; i++)
195
      {
196
          printf("#");
716 lvd 197
   }
800 DimkaM 198
      printf("\n");
199
   }
200
   printf("-------------------------\n");
201
#else
202
   }
203
#endif
716 lvd 204
 
205
   #endif
206
}
207
 
784 DimkaM 208
static void load_led()
716 lvd 209
{
784 DimkaM 210
    char ln[20]; unsigned char diskcolor = 0;
716 lvd 211
 
212
#ifdef GS_BASS
784 DimkaM 213
    if(gs.loadmod)
214
    {
215
        text_i(temp.led.load, "", 0x0D);
216
        gs.loadmod = 0;
217
    }
218
    else if(gs.loadfx)
219
    {
220
        sprintf(ln, "\x0D%d", gs.loadfx);
221
        text_i(temp.led.load, ln, 0x0D);
222
        gs.loadfx = 0;
223
    }
224
    else
716 lvd 225
#endif
784 DimkaM 226
        if(trdos_format)
227
        {
228
            diskcolor = (trdos_format < ROMLED_TIME * 3 / 4) ? 0x06 : 0x0E;
229
            trdos_format--;
230
        }
231
        else if(trdos_save)
232
        {
233
            diskcolor = (trdos_save < ROMLED_TIME * 3 / 4) ? 0x02 : 0x0A;
234
            trdos_save--;
235
        }
236
        else if(trdos_load)
237
        {
238
            diskcolor = (trdos_load < ROMLED_TIME * 3 / 4) ? 0x01 : 0x09;
239
            trdos_load--;
240
        }
241
        else if(trdos_seek)
242
        {
243
            trdos_seek--;
244
        }
245
        else if(!comp.tape.stopped)
246
        {
247
            static unsigned char tapeled[11 * 2] =
248
            {
249
                0x7F, 0xFE, 0x80, 0x01, 0x80, 0x01, 0x93, 0xC9, 0xAA, 0x55, 0x93, 0xC9,
250
                0x80, 0x01, 0x8F, 0xF1, 0x80, 0x01, 0xB5, 0xA9, 0xFF, 0xFF
251
            };
252
            const int tapecolor = 0x51;
253
            for(unsigned i = 0; i < 11; i++)
254
            {
255
                temp.led.load[pitch*i + 0] = tapeled[2 * i];
256
                temp.led.load[pitch*i + 1] = tapecolor;
257
                temp.led.load[pitch*i + 2] = tapeled[2 * i + 1];
258
                temp.led.load[pitch*i + 3] = tapecolor;
259
            }
260
            int time = (int)(temp.led.tape_started + tapeinfo[comp.tape.index].t_size - comp.t_states);
261
            if(time < 0)
262
            {
263
                find_tape_index(); time = 0;
264
                temp.led.tape_started = comp.t_states;
265
                unsigned char *ptr = tape_image + tapeinfo[comp.tape.index].pos;
266
                if(ptr == comp.tape.play_pointer && comp.tape.index)
267
                {
268
                    comp.tape.index--;
269
                    ptr = tape_image + tapeinfo[comp.tape.index].pos;
270
                }
271
                for(; ptr < comp.tape.play_pointer; ptr++)
272
                {
800 DimkaM 273
                    temp.led.tape_started -= (tape_pulse[*ptr] & tape_pulse_mask);
784 DimkaM 274
                }
275
            }
276
            time /= (conf.frame * conf.intfq);
277
            sprintf(ln, "%X:%02d", time / 60, time % 60);
278
            text_i(temp.led.load + pitch * 12 - 2, ln, 0x0D);
279
        }
280
    if(diskcolor | trdos_seek)
281
    {
282
        if(diskcolor)
283
        {
284
            unsigned *ptr = (unsigned*)temp.led.load;
285
            int i; //Alone Coder 0.36.7
286
            for(/*int*/ i = 0; i < 7; i++, ptr = (unsigned*)((char*)ptr + pitch))
287
            {
288
                *ptr = (*ptr & WORD4(0, 0xF0, 0, 0xF0)) | WORD4(0x3F, diskcolor, 0xFC, diskcolor);
289
            }
290
 
291
            static unsigned char disk[] = { 0x38, 0x1C, 0x3B, 0x9C, 0x3B, 0x9C, 0x3B, 0x9C, 0x38, 0x1C };
292
            for(i = 0; i < 5; i++, ptr = (unsigned*)((char*)ptr + pitch))
293
            {
294
                *ptr = (*ptr & WORD4(0, 0xF0, 0, 0xF0)) | WORD4(disk[2 * i], diskcolor, disk[2 * i + 1], diskcolor);
295
            }
296
        }
297
        if(comp.wd.seldrive->track != 0xFF)
298
        {
299
            sprintf(ln, "%02X", comp.wd.seldrive->track * 2 + comp.wd.side);
300
            text_i(temp.led.load + pitch - 4, ln, 0x05 + (diskcolor & 8));
301
        }
302
    }
716 lvd 303
}
304
 
305
static unsigned p_frames = 1;
306
static u64 led_updtime, p_time;
784 DimkaM 307
static double p_fps;
716 lvd 308
__inline void update_perf_led()
309
{
310
   u64 now = led_updtime - p_time;
1138 lvd 311
   if (now >= temp.cpufq) // усреднение за секунду
716 lvd 312
   {
313
      p_fps = (p_frames * temp.cpufq) / double(now) + 0.005;
314
      p_frames = 0;
315
      p_time = led_updtime;
316
   }
317
   p_frames++;
318
}
319
 
784 DimkaM 320
static void perf_led()
716 lvd 321
{
322
   char bf[0x20]; unsigned PSZ;
784 DimkaM 323
   if(conf.led.perf_t)
324
   {
325
       sprintf(bf, "%6u*%2.2f", cpu.haltpos ? cpu.haltpos : cpu.t, p_fps);
326
       PSZ = 7;
327
   }
716 lvd 328
   else
784 DimkaM 329
   {
330
       sprintf(bf, "%2.2f fps", p_fps);
331
       PSZ = 5;
332
   }
716 lvd 333
   text_i(temp.led.perf, bf, 0x0E);
334
   if (cpu.haltpos) {
335
      unsigned char *ptr = temp.led.perf + pitch*8;
336
      unsigned xx; //Alone Coder 0.36.7
337
      for (/*unsigned*/ xx = 0; xx < PSZ; xx++) *(unsigned short*)(ptr+xx*2) = 0x9A00;
338
      unsigned mx = cpu.haltpos*PSZ*8/conf.frame;
339
      for (xx = 1; xx < mx; xx++) ptr[(xx>>2)&0xFE] |= (0x80 >> (xx & 7));
340
   }
341
}
342
 
1146 lvd 343
static void breakpoints_led()
344
{
345
   if (bkpts_ena)
346
   {
347
      const char* p_Label = "Br";
348
      text_i(temp.led.bkpts, p_Label, 0x0E);
349
   }
350
}
351
 
784 DimkaM 352
static void input_led()
716 lvd 353
{
354
   if (input.kbdled != 0xFF) {
355
      unsigned char k0 = 0x99, k1 = 0x9F, k2 = 0x90;
784 DimkaM 356
      if(input.keymode == K_INPUT::KM_PASTE_HOLD)
357
      {
358
          k0 = 0xAA; k1 = 0xAF; k2 = 0xA0;
359
      }
360
      if(input.keymode == K_INPUT::KM_PASTE_RELEASE)
361
      {
362
          k0 = 0x22; k1 = 0x2F; k2 = 0x20;
363
      }
716 lvd 364
 
784 DimkaM 365
      unsigned i; //Alone Coder 0.36.7
716 lvd 366
      for (/*int*/ i = 0; i < 5; i++)
367
         temp.led.input[1+i*2*pitch] = temp.led.input[3+i*2*pitch] = k0;
784 DimkaM 368
      for(i = 0; i < 4; i++)
369
      {
370
          temp.led.input[pitch*(2 * i + 1)] = 0x7F;
371
          temp.led.input[pitch*(2 * i + 1) + 2] = 0xFE;
372
      }
716 lvd 373
      temp.led.input[pitch*1+1] = (input.kbdled & 0x08)? k2 : k1;
374
      temp.led.input[pitch*3+1] = (input.kbdled & 0x04)? k2 : k1;
375
      temp.led.input[pitch*5+1] = (input.kbdled & 0x02)? k2 : k1;
376
      temp.led.input[pitch*7+1] = (input.kbdled & 0x01)? k2 : k1;
377
      temp.led.input[pitch*1+3] = (input.kbdled & 0x10)? k2 : k1;
378
      temp.led.input[pitch*3+3] = (input.kbdled & 0x20)? k2 : k1;
379
      temp.led.input[pitch*5+3] = (input.kbdled & 0x40)? k2 : k1;
380
      temp.led.input[pitch*7+3] = (input.kbdled & 0x80)? k2 : k1;
381
   }
382
   static unsigned char joy[] =   { 0x10, 0x38, 0x1C, 0x1C, 0x1C, 0x1C, 0x08, 0x00, 0x7E, 0xFF, 0x00, 0xE7 };
383
   static unsigned char mouse[] = { 0x0C, 0x12, 0x01, 0x79, 0xB5, 0xB5, 0xB5, 0xFC, 0xFC, 0xFC, 0xFC, 0x78 };
784 DimkaM 384
   if(input.mouse_joy_led & 2)
385
   {
386
       for(size_t i = 0; i < sizeof joy; i++)
387
       {
388
           temp.led.input[4 + pitch * i] = joy[i];
389
           temp.led.input[4 + pitch * i + 1] = (temp.led.input[4 + pitch * i + 1] & 0xF0) + 0x0F;
390
       }
391
   }
392
   if(input.mouse_joy_led & 1)
393
   {
394
       for(size_t i = 0; i < sizeof mouse; i++)
395
       {
396
           temp.led.input[6 + pitch * i] = mouse[i];
397
           temp.led.input[6 + pitch * i + 1] = (temp.led.input[6 + pitch * i + 1] & 0xF0) + 0x0F;
398
       }
399
   }
716 lvd 400
   input.mouse_joy_led = 0; input.kbdled = 0xFF;
401
}
402
 
403
#ifdef MOD_MONITOR
784 DimkaM 404
static void debug_led()
716 lvd 405
{
406
   unsigned char *ptr = temp.led.osw;
407
   if (trace_rom | trace_ram) {
408
      set_banks();
409
      if (trace_rom) {
410
         const unsigned char off = 0x01, on = 0x0C;
411
         text_i(ptr + 2,           "B48", used_banks[(base_sos_rom - memory) / PAGE] ? on : off);
412
         text_i(ptr + 8,           "DOS", used_banks[(base_dos_rom - memory) / PAGE] ? on : off);
413
         text_i(ptr + pitch*8 + 2, "128", used_banks[(base_128_rom - memory) / PAGE] ? on : off);
414
         text_i(ptr + pitch*8 + 8, "SYS", used_banks[(base_sys_rom - memory) / PAGE] ? on : off);
415
         ptr += pitch*16;
416
      }
417
      if (trace_ram) {
418
         unsigned num_rows = conf.ramsize/128;
419
         unsigned j; //Alone Coder 0.36.7
420
         for (unsigned  i = 0; i < num_rows; i++) {
421
            char ln[9];
422
            for (/*unsigned*/ j = 0; j < 8; j++)
423
               ln[j] = used_banks[i*8+j]? '*' : '-';
424
            ln[j] = 0;
425
            text_i(ptr, ln, 0x0D);
426
            ptr += pitch*8;
427
         }
428
      }
429
      for (unsigned j = 0; j < MAX_PAGES; j++) used_banks[j] = 0;
430
   }
431
   for (unsigned w = 0; w < 4; w++) if (watch_enabled[w])
432
   {
433
      char bf[12]; sprintf(bf, "%8X", calc(&cpu, watch_script[w]));
434
      text_i(ptr,bf,0x0F); ptr += pitch*8;
435
   }
436
}
437
#endif
438
 
439
#ifdef MOD_MEMBAND_LED
784 DimkaM 440
static void show_mband(unsigned char *dst, unsigned start)
716 lvd 441
{
1146 lvd 442
   unsigned char* dst_m = dst + 2;
716 lvd 443
   char xx[8]; sprintf(xx, "%02X", start >> 8);
444
   text_i(dst, xx, 0x0B); dst += 4;
445
 
446
   Z80 &cpu = CpuMgr.Cpu();
447
   unsigned char band[128];
448
   unsigned i; //Alone Coder 0.36.7
449
   for (/*unsigned*/ i = 0; i < 128; i++) {
450
      unsigned char res = 0;
451
      for (unsigned q = 0; q < conf.led.bandBpp; q++)
452
         res |= cpu.membits[start++];
453
      band[i] = res;
454
   }
455
 
456
   for (unsigned p = 0; p < 16; p++, dst+=2) {
457
      unsigned char r=0, w=0, x=0;
458
      for (unsigned b = 0; b < 8; b++) {
784 DimkaM 459
          r *= 2; w *= 2; x *= 2;
716 lvd 460
         if (band[p*8+b] & MEMBITS_R) r |= 1;
461
         if (band[p*8+b] & MEMBITS_W) w |= 1;
462
         if (band[p*8+b] & MEMBITS_X) x |= 1;
463
      }
464
 
465
      unsigned char t = (p && !(p & 3))? 0x7F : 0xFF;
466
 
467
      dst[0*pitch] = t; dst[0*pitch+1] = 0x9B;
468
 
469
      dst[1*pitch] = r; dst[1*pitch+1] = 0x1C;
470
      dst[2*pitch] = r; dst[2*pitch+1] = 0x1C;
471
      dst[3*pitch] = w; dst[3*pitch+1] = 0x1A;
472
      dst[4*pitch] = w; dst[4*pitch+1] = 0x1A;
473
      dst[5*pitch] = x; dst[5*pitch+1] = 0x1F;
474
      dst[6*pitch] = x; dst[6*pitch+1] = 0x1F;
475
 
476
      dst[7*pitch] = t; dst[7*pitch+1] = 0x9B;
477
   }
478
 
479
   sprintf(xx, "%02X", (start-1) >> 8);
480
   text_i(dst, xx, 0x0B, 2);
481
 
784 DimkaM 482
   for(i = 0; i < 8; i++)
483
   {
484
       dst[i*pitch] |= 0x80;
1146 lvd 485
     //dst[i*pitch - 17LL * 2LL] |= 0x01;
486
       dst_m[i * pitch] |= 0x01;
784 DimkaM 487
   }
716 lvd 488
}
489
 
784 DimkaM 490
static void memband_led()
716 lvd 491
{
492
   unsigned char *dst = temp.led.memband;
493
   for (unsigned start = 0x0000; start < 0x10000;) {
494
      show_mband(dst, start);
495
      start += conf.led.bandBpp * 128;
496
      dst += 10*pitch;
497
   }
498
 
499
   Z80 &cpu = CpuMgr.Cpu();
500
   for (unsigned i = 0; i < 0x10000; i++)
784 DimkaM 501
      cpu.membits[i] &= ripper | unsigned(~(MEMBITS_R | MEMBITS_W | MEMBITS_X));
716 lvd 502
}
503
#endif
504
 
505
 
506
HANDLE hndKbdDev;
507
 
508
void init_leds()
509
{
510
   DefineDosDevice(DDD_RAW_TARGET_PATH, "Kbd_unreal_spec", "\\Device\\KeyboardClass0");
784 DimkaM 511
   hndKbdDev = CreateFile("\\\\.\\Kbd_unreal_spec", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
512
   if(hndKbdDev == INVALID_HANDLE_VALUE)
513
   {
514
       hndKbdDev = nullptr;
515
       conf.led.flash_ay_kbd = 0;
516
   }
716 lvd 517
}
518
 
519
void done_leds()
520
{
521
   if (hndKbdDev) {
784 DimkaM 522
      DefineDosDevice(DDD_REMOVE_DEFINITION, "Kbd_unreal_spec", nullptr);
523
      CloseHandle(hndKbdDev); hndKbdDev = nullptr;
716 lvd 524
   }
525
}
526
 
784 DimkaM 527
static void ay_kbd()
716 lvd 528
{
529
   static unsigned char pA, pB, pC;
784 DimkaM 530
   static unsigned prev_keyled = -1U;
716 lvd 531
 
532
   KEYBOARD_INDICATOR_PARAMETERS InputBuffer;
533
   InputBuffer.LedFlags = InputBuffer.UnitId = 0;
534
 
535
   if (ay[0].get_reg( 8) > pA) InputBuffer.LedFlags |= KEYBOARD_NUM_LOCK_ON;
536
   if (ay[0].get_reg( 9) > pB) InputBuffer.LedFlags |= KEYBOARD_CAPS_LOCK_ON;
537
   if (ay[0].get_reg(10) > pC) InputBuffer.LedFlags |= KEYBOARD_SCROLL_LOCK_ON;
538
 
784 DimkaM 539
   pA = ay[0].get_reg(8); pB = ay[0].get_reg(9); pC = ay[0].get_reg(10);
716 lvd 540
 
541
   DWORD xx;
784 DimkaM 542
   if(prev_keyled != InputBuffer.LedFlags)
543
   {
544
       prev_keyled = InputBuffer.LedFlags;
545
       DeviceIoControl(hndKbdDev, IOCTL_KEYBOARD_SET_INDICATORS, &InputBuffer, sizeof(KEYBOARD_INDICATOR_PARAMETERS),
546
           nullptr, 0, &xx, nullptr);
547
   }
716 lvd 548
}
549
 
784 DimkaM 550
static void key_led()
716 lvd 551
{
784 DimkaM 552
   #define key_x 1U
553
   #define key_y 1U
554
   unsigned i; //Alone Coder 0.36.7
716 lvd 555
   for (/*int*/ i = 0; i < 9; i++) text_16(rbuf+(key_y+i)*pitch*16+key_x*2, "                                 ", 0x40);
556
   static char ks[] = "cZXCVASDFGQWERT1234509876POIUYeLKJHssMNB";
557
   for (i = 0; i < 8; i++) {
784 DimkaM 558
      for (unsigned j = 0; j < 5; j++) {
716 lvd 559
         unsigned x, y, at;
784 DimkaM 560
         if(i < 4)
561
         {
562
             y = 7 - 2 * i + key_y;
563
             x = 3 * j + 2 + key_x;
564
         }
565
         else
566
         {
567
             y = 2 * (i - 4) + 1 + key_y;
568
             x = 29 - 3 * j + key_x;
569
         }
570
         unsigned a = u8(ks[i*5+j])*0x100U+u8(' ');
716 lvd 571
         at = (input.kbd[i] & (1<<j))? 0x07 : ((input.rkbd[i] & (1<<j)) ? 0xA0:0xD0);
784 DimkaM 572
         text_16(rbuf + 2 * x + y * pitch * 16, (char*)&a, u8(at));
716 lvd 573
      }
574
   }
575
}
576
 
784 DimkaM 577
static void time_led()
716 lvd 578
{
579
   static u64 prev_time;
580
   static char bf[8];
581
   if (led_updtime - prev_time > 5000) {
582
      prev_time = led_updtime;
583
      SYSTEMTIME st; GetLocalTime(&st);
584
      sprintf(bf, "%2d:%02d", st.wHour, st.wMinute);
585
   }
586
   text_i(temp.led.time, bf, 0x0D);
587
}
588
 
1138 lvd 589
// Вызывается раз в кадр
716 lvd 590
void showleds()
591
{
592
   led_updtime = rdtsc();
593
   update_perf_led();
594
 
595
   if (temp.vidblock) return;
596
 
597
   pitch = temp.scx/4;
598
 
599
   if (statcnt) { statcnt--; text_i(rbuf + ((pitch/2-strlen(statusline)*6/8) & 0xFE) + (temp.scy-10)*pitch, statusline, 0x09); }
600
 
601
   if (!conf.led.enabled) return;
602
 
603
   if (temp.led.ay) ay_led();
604
   if (temp.led.perf) perf_led();
605
   if (temp.led.load) load_led();
606
   if (temp.led.input) input_led();
607
   if (temp.led.time) time_led();
608
#ifdef MOD_MONITOR
609
   if (temp.led.osw) debug_led();
610
#endif
611
#ifdef MOD_MEMBAND_LED
612
   if (temp.led.memband) memband_led();
613
#endif
614
   if (conf.led.flash_ay_kbd && hndKbdDev) ay_kbd();
615
   if (input.keymode == K_INPUT::KM_KEYSTICK) key_led();
1146 lvd 616
   if(temp.led.bkpts) breakpoints_led();
716 lvd 617
}