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 | } |