1 /***************************************************************************
3 * ZXEmuT -- ZX Spectrum Emulator with Tcl scripting
5 * Copyright (C) 2012-2022 Ketmar Dark <ketmar@ketmar.no-ip.org>
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 3 of the License ONLY.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **************************************************************************/
20 #define MV_FAST_RECODE
22 #include "../libzymosis/zymosis.h"
23 #include "libvideo/video.h"
25 #include "emucommon.h"
31 // ////////////////////////////////////////////////////////////////////////// //
33 static const uint8_t cp1251to866
[256] = {
34 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
35 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
36 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
37 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
38 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
39 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
40 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
41 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
42 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
43 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
44 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
45 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
46 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
47 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
48 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,
49 0xa8,0xb8,0xaa,0xba,0xaf,0xbf,0xa1,0xa2,0xb0,0x00,0xb7,0x00,0xb9,0xa4,0x00,0xa0,
54 static const uint16_t charMap1251
[128] = {
55 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021,0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F,
56 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,0x003F,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F,
57 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7,0x0401,0x00A9,0x0404,0x00AB,0x00AC,0x00AD,0x00AE,0x0407,
58 0x00B0,0x00B1,0x0406,0x0456,0x0491,0x00B5,0x00B6,0x00B7,0x0451,0x2116,0x0454,0x00BB,0x0458,0x0405,0x0455,0x0457,
59 0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041A,0x041B,0x041C,0x041D,0x041E,0x041F,
60 0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042A,0x042B,0x042C,0x042D,0x042E,0x042F,
61 0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043A,0x043B,0x043C,0x043D,0x043E,0x043F,
62 0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044A,0x044B,0x044C,0x044D,0x044E,0x044F,
65 static const uint16_t charMap866
[128] = {
66 0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041A,0x041B,0x041C,0x041D,0x041E,0x041F,
67 0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042A,0x042B,0x042C,0x042D,0x042E,0x042F,
68 0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043A,0x043B,0x043C,0x043D,0x043E,0x043F,
69 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255D,0x255C,0x255B,0x2510,
70 0x2514,0x2534,0x252C,0x251C,0x2500,0x253C,0x255E,0x255F,0x255A,0x2554,0x2569,0x2566,0x2560,0x2550,0x256C,0x2567,
71 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256B,0x256A,0x2518,0x250C,0x2588,0x2584,0x258C,0x2590,0x2580,
72 0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044A,0x044B,0x044C,0x044D,0x044E,0x044F,
73 0x0401,0x0451,0x0404,0x0454,0x0407,0x0457,0x040E,0x045E,0x00B0,0x2219,0x00B7,0x221A,0x2116,0x00A4,0x25A0,0x00A0,
77 static uint8_t table1251to866
[65536];
78 static int tableRCInited
= 0;
81 //==========================================================================
85 //==========================================================================
86 static void initTableRC (void) {
88 memset(table1251to866
, '.', sizeof(table1251to866
));
89 for (uint16_t f
= 0; f
< 128; ++f
) table1251to866
[f
] = (uint8_t)f
;
90 for (uint16_t f
= 0; f
< 128; ++f
) {
91 const uint16_t code
= charMap1251
[f
];
92 for (uint16_t c
= 0; c
< 128; ++c
) {
93 if (charMap866
[c
] == code
) {
94 table1251to866
[f
+128U] = (uint8_t)(c
+128U);
102 // ////////////////////////////////////////////////////////////////////////// //
103 int memviewActive
= 0;
104 uint8_t mv_pagemap
[256];
107 uint32_t mv_staddr
= 0x5B00;
108 int mv_encoding
= MV_ENC_7BIT
;
109 int mv_viewmode
= MV_MODE_HEX
;
110 int mv_textwidth
= 64;
111 uint8_t mv_textcolor
= 7; // paper is ignored
113 static int inaddrpos
= -1;
114 static int mmeditpos
= 0;
115 static int mmeditactive
= 0;
117 static vt_simple_menu
*current_menu
= NULL
;
118 static void (*menu_sel_cb
) (uint32_t sel
) = NULL
;
119 static vt_simple_menu wkmenu
;
121 static int evtCtrlKeyDown
= 0;
122 static int evtAltKeyDown
= 0;
123 static int evtShiftKeyDown
= 0;
126 //==========================================================================
130 //==========================================================================
131 static inline uint16_t recodeByte (uint16_t b
) {
132 if (mv_encoding
== MV_ENC_1251
) {
133 #ifdef MV_FAST_RECODE
136 if (!tableRCInited
) initTableRC();
137 b
= table1251to866
[b
];
140 if (mv_encoding
== MV_ENC_7BIT
) b
&= 0x7f;
141 if (b
< 32 || b
== 127) b
= '.'|0x8000;
142 else if (b
== 32 && mv_viewmode
== MV_MODE_HEX
) b
= '.'|0x4000;
147 //==========================================================================
151 //==========================================================================
152 static __attribute__((always_inline
)) inline int isAddrEditActive (void) {
153 return (inaddrpos
>= 0);
157 //==========================================================================
161 //==========================================================================
162 static __attribute__((always_inline
)) inline int isMMEditActive (void) {
167 //==========================================================================
171 //==========================================================================
172 static __attribute__((always_inline
)) inline uint8_t getByte (uint32_t addr
) {
175 z80
.mem_read(&z80
, addr
, ZYM_MEMIO_OTHER
) :
176 zxMemoryBanks
[mv_pagemap
[((addr
>>14)-4)%(unsigned)zxMaxMemoryBank
]][addr
&0x3fffU
];
180 //==========================================================================
184 //==========================================================================
185 static void memviewResetMMap (int inorder
) {
186 for (uint32_t f
= 0; f
< 256; ++f
) mv_pagemap
[f
] = f
;
194 //==========================================================================
198 //==========================================================================
199 void memviewInit (void) {
204 //==========================================================================
208 //==========================================================================
209 void memviewSetActive (int st
) {
210 memviewActive
= !!st
;
214 //==========================================================================
218 //==========================================================================
219 static __attribute__((unused
)) void drawAllChars (void) {
220 for (int y
= 0; y
< 16; ++y
) {
221 for (int x
= 0; x
< 16; ++x
) {
222 vt_writechar(x
, y
, y
*16+x
, 0x0f);
225 for (int x
= 0; x
< 16; ++x
) {
226 vt_writechar(x
, VID_TEXT_HEIGHT
-1, '*', (x
<<4)|(x
< 8 ? 15 : 0));
231 //==========================================================================
235 //==========================================================================
236 static void drawMMap (void) {
240 vt_draw_frame_ex(xofs
-2, yofs
-1, 3*8+3, 10, 0x50,
241 VID_FRAME_DOUBLE
|VID_FRAME_OVERWRITE
|VID_FRAME_FILL
,
244 for (int y
= 0; y
< 8; ++y
) {
245 for (int x
= 0; x
< 8; ++x
) {
247 if (y
*8+x
== mmeditpos
/2) {
250 attr
= (zxMemBanksDirty
[mv_pagemap
[y
*8+x
]] ? 0x50 : 0x51);
252 vt_writef(xofs
+x
*3, yofs
+y
, attr
, "%02X", mv_pagemap
[y
*8+x
]);
256 const int cx
= mmeditpos
%16;
257 const int cy
= mmeditpos
/16;
258 vt_writeattr(xofs
+(cx
/2)*3+(cx
%2), yofs
+cy
, emuGetCursorColor(0xF0, 0x70));
262 //==========================================================================
266 //==========================================================================
267 static void writeAddrAt (int x
, int y
, uint32_t addr
) {
270 if (addr
<= 0xffffU
) {
271 snprintf(buf
, sizeof(buf
), ".. %04X", addr
);
272 dirty
= zxMemBanksDirty
[zxMemoryBankNum
[addr
>>14]];
274 snprintf(buf
, sizeof(buf
), "%02X %04X", ((addr
>>14)-4)%zxMaxMemoryBank
, addr
&0x3fffU
);
275 dirty
= zxMemBanksDirty
[mv_pagemap
[((addr
>>14)-4)%(unsigned)zxMaxMemoryBank
]];
277 vt_writestrcnt(x
, y
, buf
, 7, 0x05);
278 if (!dirty
) vt_writeattrs(x
, y
, 2, 0x03);
282 //==========================================================================
286 //==========================================================================
287 static void drawHexView (void) {
289 const int mhgt
= VID_TEXT_HEIGHT
-2;
290 uint32_t addr
= mv_staddr
;
291 vt_draw_frame(1, 0, 78, mhgt
+2, 15, VID_FRAME_SINGLE
);
294 for (int dy
= 0; dy
< mhgt
; ++dy
) {
295 writeAddrAt(xofs
, dy
+yofs
, addr
);
297 for (int dx
= 0; dx
< 16; ++dx
) {
298 if (addr
<= 0xffffU
&& addr
+(unsigned)dx
> 0xffffU
) break;
299 uint8_t b
= getByte(addr
+(unsigned)dx
);
300 snprintf(buf
, sizeof(buf
), "%02X", b
);
301 vt_writestrz(xofs
+8+dx
*3+(dx
>= 8), dy
+yofs
, buf
, 7);
304 for (int dx
= 0; dx
< 16; ++dx
) {
305 if (addr
<= 0xffffU
&& addr
+(unsigned)dx
> 0xffffU
) break;
306 uint16_t b
= recodeByte(getByte(addr
+(unsigned)dx
));
307 vt_writechar(xofs
+8+16*3+2+dx
+(dx
>= 8), dy
+yofs
, (char)b
,
308 (b
<= 0xff ? mv_textcolor
: (b
&0x8000 ? 5 : mv_textcolor
)+(b
&0x4000 ? 0x10 : 0)));
316 //==========================================================================
320 //==========================================================================
321 static uint32_t goLineUp (uint32_t addr
) {
323 uint8_t b
= getByte(addr
-1U);
324 const int skiptsp
= (b
== 10 || b
== 13);
327 if (addr
&& getByte(addr
-1U) == 13) --addr
;
329 } else if (b
== 13) {
333 int zerostate
= -1; // <0:haven't seen; 0:non-zero seen; 1:only zero seen
334 // skip trailing spaces
336 while (addr
&& getByte(addr
-1U) == 32) {
341 const uint32_t orgaddr
= addr
;
342 int count
= mv_textwidth
;
343 while (addr
&& count
--) {
344 b
= getByte(addr
-1U);
345 if (b
== 13 || b
== 10) return addr
;
347 if (zerostate
== 0) return addr
; // seen non-zero
348 zerostate
= 1; // only zero seen
350 if (zerostate
== 1) return addr
;
351 zerostate
= 0; // seen non-zero
355 return (addr
? orgaddr
-mv_textwidth
: 0);
359 //==========================================================================
363 //==========================================================================
364 static uint32_t goLineDown (uint32_t addr
) {
365 const uint32_t orgaddr
= addr
;
366 int count
= mv_textwidth
;
367 int zerostate
= -1; // <0:haven't seen; 0:non-zero seen; 1:only zero seen
369 while (addr
&& count
--) {
371 if (b
== 13 || b
== 10) {
372 if (b
== 13 && getByte(addr
) == 10) ++addr
;
376 if (zerostate
== 0) return addr
-1; // seen non-zero
377 zerostate
= 1; // only zero seen
379 if (zerostate
== 1) return addr
-1;
380 zerostate
= 0; // seen non-zero
383 addr
= orgaddr
+mv_textwidth
;
384 // check for trailing spaces
385 while (getByte(addr
) == 32) ++addr
;
387 if (b
== 13) b
= getByte(++addr
);
393 //==========================================================================
397 //==========================================================================
398 static void drawTextView (void) {
401 uint32_t addr
= mv_staddr
;
402 vt_draw_frame(1, 0, 78, VID_TEXT_HEIGHT
, 15, VID_FRAME_SINGLE
);
403 for (int y
= 0; y
< VID_TEXT_HEIGHT
-2; ++y
) {
404 writeAddrAt(xofs
, y
+yofs
, addr
);
405 uint32_t eaddr
= goLineDown(addr
);
406 if (eaddr
> addr
&& getByte(eaddr
-1) == 10) --eaddr
;
407 if (eaddr
> addr
&& getByte(eaddr
-1) == 13) --eaddr
;
408 const uint32_t naddr
= eaddr
;
409 if (eaddr
-addr
> mv_textwidth
) eaddr
= addr
+mv_textwidth
;
410 int xxofs
= (MV_MAX_TEXT_WIDTH
-mv_textwidth
)/2;
411 const uint32_t len
= eaddr
-addr
;
412 for (uint32_t x
= 0; x
< len
; ++x
) {
413 uint16_t b
= recodeByte(getByte(addr
++));
414 vt_writechar(xofs
+8+xxofs
+x
, y
+yofs
, (char)b
,
415 (b
<= 0xff ? mv_textcolor
: (b
&0x8000 ? 5 : mv_textcolor
)+(b
&0x4000 ? 0x10 : 0)));
417 // check for trailing spaces
419 while (getByte(addr
) == 32) ++addr
;
420 if (getByte(addr
) == 13) ++addr
;
421 if (getByte(addr
) == 10) ++addr
;
423 vt_writef(7, 0, 0x05, "[wdt:%d]", mv_textwidth
);
427 //==========================================================================
431 //==========================================================================
432 void memviewDraw (void) {
433 //vt_cls(0xb0, 0x01);
436 if (mv_viewmode
== MV_MODE_HEX
) drawHexView(); else drawTextView();
438 switch (mv_encoding
) {
439 case MV_ENC_7BIT
: vt_writestrz(2+70, 0, "[7bit]", 4); break;
440 case MV_ENC_1251
: vt_writestrz(2+68, 0, "[cp1251]", 4); break;
441 case MV_ENC_866
: vt_writestrz(2+69, 0, "[cp866]", 4); break;
444 // draw physical page
447 if (mv_staddr
<= 0xffffU
) {
448 pg
= zxMemoryBankNum
[mv_staddr
>>14];
450 pg
= mv_pagemap
[((mv_staddr
>>14)-4)%(unsigned)zxMaxMemoryBank
];
452 uint8_t attr
= (zxMemBanksDirty
[pg
] ? 0x04 : 0x03);
453 vt_writef(2, 0, attr
, "[%02X]", pg
);
456 if (isAddrEditActive()) {
457 vt_writeattr(2+inaddrpos
+(inaddrpos
>= 2), 1, emuGetCursorColor(0xF0, 0x70));
458 } else if (isMMEditActive()) {
462 if (current_menu
) vt_smm_draw(current_menu
);
470 //==========================================================================
474 //==========================================================================
475 static void doLeft (void) {
476 if (isAddrEditActive()) {
477 if (inaddrpos
) --inaddrpos
;
480 if (isMMEditActive()) {
481 if (mmeditpos
> 0) --mmeditpos
;
484 if (mv_staddr
) --mv_staddr
;
488 //==========================================================================
492 //==========================================================================
493 static void doRight (void) {
494 if (isAddrEditActive()) {
495 if (inaddrpos
< 5) ++inaddrpos
;
498 if (isMMEditActive()) {
499 if (mmeditpos
< 64*2-1) ++mmeditpos
;
506 //==========================================================================
510 //==========================================================================
511 static void doUp (void) {
512 if (isAddrEditActive()) {
513 if (inaddrpos
>= 2) inaddrpos
= 0;
516 if (isMMEditActive()) {
517 if (mmeditpos
>= 8*2) mmeditpos
-= 8*2;
520 if (mv_viewmode
== MV_MODE_TEXT
) {
521 uint32_t nn
= goLineUp(mv_staddr
);
522 if (mv_staddr
> 0xffffU
&& nn
<= 0xffffU
) nn
= 0x010000U
;
526 if (mv_staddr
<= 0xffffU
) {
527 if (mv_staddr
< 16) mv_staddr
= 0; else mv_staddr
-= 16;
534 //==========================================================================
538 //==========================================================================
539 static void doDown (void) {
540 if (isAddrEditActive()) {
541 if (inaddrpos
< 2) inaddrpos
= 2;
544 if (isMMEditActive()) {
545 if (mmeditpos
+8*2 < 64*2) mmeditpos
+= 8*2;
548 if (mv_viewmode
== MV_MODE_TEXT
) {
549 mv_staddr
= goLineDown(mv_staddr
);
556 //==========================================================================
560 //==========================================================================
561 static void doPageUp (void) {
562 if (isAddrEditActive()) {
563 if (mv_staddr
> 0xffffU
) {
564 uint32_t pg
= (mv_staddr
>>14)-4;
566 mv_staddr
= (pg
+4)<<14;
570 if (isMMEditActive()) return;
571 if (mv_viewmode
== MV_MODE_TEXT
) {
572 for (int f
= 0; f
< VID_TEXT_HEIGHT
-3; ++f
) {
573 uint32_t nn
= goLineUp(mv_staddr
);
574 if (mv_staddr
> 0xffffU
&& nn
<= 0xffffU
) nn
= 0x010000U
;
579 if (mv_staddr
<= 0xffffU
) {
580 if (mv_staddr
< 16*(VID_TEXT_HEIGHT
-2)) mv_staddr
= 0; else mv_staddr
-= 16*(VID_TEXT_HEIGHT
-2);
582 mv_staddr
-= 16*(VID_TEXT_HEIGHT
-2);
587 //==========================================================================
591 //==========================================================================
592 static void doPageDown (void) {
593 if (isAddrEditActive()) {
594 if (mv_staddr
<= 0xffffU
) {
595 mv_staddr
= 0x010000U
;
597 uint32_t pg
= (mv_staddr
>>14)-4;
598 if (pg
+1 < (uint32_t)zxMaxMemoryBank
) mv_staddr
= (pg
+5)<<14;
602 if (isMMEditActive()) return;
603 if (mv_viewmode
== MV_MODE_TEXT
) {
604 for (int f
= 0; f
< VID_TEXT_HEIGHT
-3; ++f
) {
605 mv_staddr
= goLineDown(mv_staddr
);
609 if (mv_staddr
<= 0xffffU
) {
610 if (mv_staddr
+16*(VID_TEXT_HEIGHT
-2) > 0xffffU
) mv_staddr
= 0x10000U
-16; else mv_staddr
+= 16*(VID_TEXT_HEIGHT
-2);
612 mv_staddr
+= 16*(VID_TEXT_HEIGHT
-2);
617 //==========================================================================
621 //==========================================================================
622 static void menu_set_encoding (uint32_t sel
) {
623 mv_encoding
= (int)sel
;
627 //==========================================================================
629 // menu_set_text_width
631 //==========================================================================
632 static void menu_set_text_width (uint32_t sel
) {
633 const int wdts
[5] = {32, 42, 51, 64, MV_MAX_TEXT_WIDTH
};
634 mv_textwidth
= wdts
[sel
];
638 //==========================================================================
640 // menu_set_text_bright
642 //==========================================================================
643 static void menu_set_text_bright (uint32_t sel
) {
644 mv_textcolor
&= 0x07;
645 mv_textcolor
|= (sel
? 0x08 : 0x00);
649 //==========================================================================
651 // menu_set_text_color
653 //==========================================================================
654 static void menu_set_text_color (uint32_t sel
) {
655 mv_textcolor
= (mv_textcolor
&0x08)|(sel
+1);
659 //==========================================================================
661 // menu_set_view_mode
663 //==========================================================================
664 static void menu_set_view_mode (uint32_t sel
) {
665 mv_viewmode
= (int)sel
;
669 //==========================================================================
673 //==========================================================================
674 int memviewKeyEvent (SDL_KeyboardEvent
*key
) {
676 int mrs
= vt_smm_process_key(current_menu
, key
);
679 vt_smm_deinit(current_menu
);
682 case VID_SMM_NOTMINE
:
686 case VID_SMM_SELECTED
:
688 const uint32_t cy
= current_menu
->cursor_y
;
689 vt_smm_deinit(current_menu
);
693 vt_smm_deinit(current_menu
);
701 if (key
->type
!= SDL_KEYDOWN
) return 1;
703 evtCtrlKeyDown
= !!(key
->keysym
.mod
&KMOD_CTRL
);
704 evtAltKeyDown
= !!(key
->keysym
.mod
&KMOD_ALT
);
705 evtShiftKeyDown
= !!(key
->keysym
.mod
&KMOD_SHIFT
);
707 if (isAddrEditActive() && key
->keysym
.unicode
> 32 && key
->keysym
.unicode
< 127) {
708 int d
= digitInBase((char)key
->keysym
.unicode
, 16);
711 uint32_t pg
= (mv_staddr
> 0xffffU
? (mv_staddr
>>14)-4 : 0);
712 pg
&= (inaddrpos
? 0xf0U
: 0x0fU
);
713 pg
|= ((unsigned)d
)<<((1-inaddrpos
)*4);
714 mv_staddr
= (mv_staddr
&0x3fffU
)|((pg
+4)<<14);
716 if (mv_staddr
> 0xffffU
&& inaddrpos
== 2 && d
> 3) return 1;
717 if (mv_staddr
> 0xffffU
) {
718 uint32_t pg
= (mv_staddr
>>14);
719 mv_staddr
&= ~(0x000fU
<<((5-inaddrpos
)*4));
720 mv_staddr
|= ((unsigned)d
)<<((5-inaddrpos
)*4);
723 mv_staddr
&= ~(0x000fU
<<((5-inaddrpos
)*4));
724 mv_staddr
|= ((unsigned)d
)<<((5-inaddrpos
)*4);
727 if (inaddrpos
< 5) ++inaddrpos
;
732 if (isMMEditActive() && key
->keysym
.unicode
> 32 && key
->keysym
.unicode
< 127) {
733 int d
= digitInBase((char)key
->keysym
.unicode
, 16);
735 const int mmindex
= mmeditpos
/2;
736 uint8_t v
= mv_pagemap
[mmindex
];
737 if (mmeditpos
%2 == 0) {
745 if (mv_pagemap
[mmindex
] != v
) {
747 while (swidx
< 64 && mv_pagemap
[swidx
] != v
) ++swidx
;
749 uint8_t vtmp
= mv_pagemap
[swidx
];
750 mv_pagemap
[swidx
] = mv_pagemap
[mmindex
];
751 mv_pagemap
[mmindex
] = vtmp
;
753 mv_pagemap
[mmindex
] = v
;
757 if (mmeditpos
>= 64*2) mmeditpos
= 64*2-1;
762 switch (key
->keysym
.sym
) {
766 if (isAddrEditActive()) inaddrpos
= -1;
767 else if (isMMEditActive()) mmeditactive
= 0;
768 else memviewSetActive(0);
772 if (isMMEditActive()) {
773 // go to the selected physical page
774 mv_staddr
= (((mmeditpos
/2)+4)<<14);
780 case SDLK_DELETE
: case SDLK_KP_PERIOD
:
781 if (isAddrEditActive()) {
782 if (inaddrpos
< 2) mv_staddr
&= 0xffffU
;
783 } else if (isMMEditActive()) {
784 if (evtShiftKeyDown
) memviewResetMMap(0);
785 else if (evtCtrlKeyDown
) memviewResetMMap(1);
786 else if (evtAltKeyDown
) {
791 } else if (!evtShiftKeyDown
&& !evtCtrlKeyDown
&& !evtAltKeyDown
) {
792 const int mmindex
= mmeditpos
/2;
793 uint8_t v
= (uint8_t)mmindex
;
794 if (mv_pagemap
[mmindex
] != v
) {
796 while (swidx
< 64 && mv_pagemap
[swidx
] != v
) ++swidx
;
798 uint8_t vtmp
= mv_pagemap
[swidx
];
799 mv_pagemap
[swidx
] = mv_pagemap
[mmindex
];
800 mv_pagemap
[mmindex
] = vtmp
;
802 mv_pagemap
[mmindex
] = v
;
810 mv_viewmode
= !mv_viewmode
; // we have only two for now
813 case SDLK_LEFT
: case SDLK_KP4
: doLeft(); return 1;
814 case SDLK_RIGHT
: case SDLK_KP6
: doRight(); return 1;
815 case SDLK_UP
: case SDLK_KP8
: doUp(); return 1;
816 case SDLK_DOWN
: case SDLK_KP2
: doDown(); return 1;
817 case SDLK_PAGEUP
: case SDLK_KP9
: case SDLK_o
: doPageUp(); return 1;
818 case SDLK_PAGEDOWN
: case SDLK_KP3
: case SDLK_p
: doPageDown(); return 1;
819 case SDLK_BACKSPACE
: if (isAddrEditActive()) doLeft(); return 1;
822 if (isAddrEditActive()) return 1;
823 if (mv_viewmode
== MV_MODE_TEXT
) {
824 if ((key
->keysym
.mod
&KMOD_SHIFT
) != 0) doPageUp(); else doPageDown();
829 if (isAddrEditActive()) return 1;
830 if (mv_viewmode
== MV_MODE_TEXT
) mv_textwidth
= 32;
833 if (isAddrEditActive()) return 1;
834 if (mv_viewmode
== MV_MODE_TEXT
) mv_textwidth
= 42;
837 if (isAddrEditActive()) return 1;
838 if (mv_viewmode
== MV_MODE_TEXT
) mv_textwidth
= 51;
841 if (isAddrEditActive()) return 1;
842 if (mv_viewmode
== MV_MODE_TEXT
) mv_textwidth
= 64;
845 if (isAddrEditActive()) return 1;
846 if (mv_viewmode
== MV_MODE_TEXT
) mv_textwidth
= MV_MAX_TEXT_WIDTH
;
849 case SDLK_HOME
: case SDLK_KP7
:
850 if (isAddrEditActive()) inaddrpos
= (inaddrpos
> 2 ? 2 : 0);
852 case SDLK_END
: case SDLK_KP1
:
853 if (isAddrEditActive()) inaddrpos
= (inaddrpos
< 2 ? 2 : 5);
857 if (!isAddrEditActive()) {
858 if ((key
->keysym
.mod
&KMOD_ALT
) != 0) {
859 vt_smm_init(&wkmenu
, "Text brightness", (const char *[]){"off", "on", NULL
});
860 menu_sel_cb
= &menu_set_text_bright
;
861 wkmenu
.cursor_y
= (mv_textcolor
>= 0x08 ? 1 : 0);
862 current_menu
= &wkmenu
;
864 mv_textcolor
^= 0x08;
870 if (!isAddrEditActive()) {
871 if ((key
->keysym
.mod
&KMOD_ALT
) != 0) {
872 vt_smm_init(&wkmenu
, "Text color", (const char *[]){
873 "blue", "red", "magenta", "green", "cyan", "yellow", "white",
875 menu_sel_cb
= &menu_set_text_color
;
876 wkmenu
.cursor_y
= (mv_textcolor
&0x07)-1;
877 current_menu
= &wkmenu
;
879 mv_textcolor
= ((mv_textcolor
+1)&0x07)|(mv_textcolor
&0x08);
880 if (!mv_textcolor
) mv_textcolor
= 1;
881 else if (mv_textcolor
== 8) mv_textcolor
= 9;
887 if ((key
->keysym
.mod
&KMOD_ALT
) != 0) {
888 vt_smm_init(&wkmenu
, "Encoding", (const char *[]){"7 bit", "CP 866", "CP 1251", NULL
});
889 menu_sel_cb
= &menu_set_encoding
;
890 wkmenu
.cursor_y
= (uint32_t)mv_encoding
;
891 current_menu
= &wkmenu
;
893 if (!isAddrEditActive()) memviewSetActive(0);
898 if (!isAddrEditActive()) inaddrpos
= 2;
902 if ((key
->keysym
.mod
&KMOD_ALT
) != 0) {
903 vt_smm_init(&wkmenu
, "View mode", (const char *[]){"hex", "text", NULL
});
904 menu_sel_cb
= &menu_set_view_mode
;
905 wkmenu
.cursor_y
= (uint32_t)mv_viewmode
;
906 current_menu
= &wkmenu
;
911 if ((key
->keysym
.mod
&KMOD_ALT
) != 0 && mv_viewmode
== MV_MODE_TEXT
) {
912 vt_smm_init(&wkmenu
, "Text width", (const char *[]){"32", "42", "51", "64", "max", NULL
});
913 menu_sel_cb
= &menu_set_text_width
;
914 if (mv_textwidth
<= 32) wkmenu
.cursor_y
= 0;
915 else if (mv_textwidth
<= 42) wkmenu
.cursor_y
= 1;
916 else if (mv_textwidth
<= 51) wkmenu
.cursor_y
= 2;
917 else if (mv_textwidth
<= 64) wkmenu
.cursor_y
= 3;
918 else wkmenu
.cursor_y
= 4;
919 current_menu
= &wkmenu
;
924 if (isAddrEditActive()) return 1;
925 if (!isMMEditActive()) mmeditactive
= 1;
929 if ((key
->keysym
.mod
&(KMOD_ALT
|KMOD_SHIFT
)) == 0) {
936 if (!isAddrEditActive() && !isMMEditActive()) {
937 if ((key
->keysym
.mod
&(KMOD_ALT
|KMOD_SHIFT
)) == 0) {
938 int v
= ((optPaused
&PAUSE_PERMANENT_MASK
) == 0);
939 emuSetPaused(v
? PAUSE_PERMANENT_SET
: PAUSE_PERMANENT_RESET
);
945 /*if ((key->keysym.mod&KMOD_ALT) != 0)*/ {
946 if (isAddrEditActive()) {
947 vt_smm_init_textview(&wkmenu
, "Small help (MM)",
949 "dunno, cursor keys. pgup/pgdn moves by pages.",
950 "del on page number clears page index.",
953 } else if (isMMEditActive()) {
954 vt_smm_init_textview(&wkmenu
, "Small help (AE)",
956 "\x01""C-Del", " restore pages in order",
957 "\x01""S-Del", " restore pages in 502 order",
958 "\x01""M-Del", " restore pages in 201 order",
959 "\x01""Del", " make current page ordered",
963 vt_smm_init_textview(&wkmenu
, "Small help",
965 "\x01""F6", " switch view mode",
966 //"\x01""F8", " switch encoding",
967 "\x01""G", " input address",
968 "\x01""C", " cycle text colors",
969 "\x01""B", " toggle text brightness",
970 "\x01""0-4", " set text width",
971 "\x01""M-E", " select encoding",
972 "\x01""M-W", " select text width",
973 "\x01""M-M", " select view mode",
978 current_menu
= &wkmenu
;