1 #include "extras.h"
2 #include "emu.h"
3 #include "mem.h"
4 #include "defines.h"
5 
6 /* A few needed locations */
7 #define CE_kbdScanCode  0xD00587
8 #define CE_kbdFlags     0xD00080
9 #define CE_kbdSCR       (1 << 3)
10 #define CE_kbdKey       0xD0058C
11 #define CE_keyExtend    0xD0058E
12 #define CE_graphFlags2  0xD0009F
13 #define CE_keyReady     (1 << 5)
14 
sendCSC(uint8_t csc)15 bool EMSCRIPTEN_KEEPALIVE sendCSC(uint8_t csc) {
16     uint8_t flags = mem_peek_byte(CE_kbdFlags);
17     if (flags & CE_kbdSCR) {
18         return false;
19     }
20     mem_poke_byte(CE_kbdScanCode, csc);
21     mem_poke_byte(CE_kbdFlags, flags | CE_kbdSCR);
22     return true;
23 }
24 
sendKey(uint16_t key)25 bool EMSCRIPTEN_KEEPALIVE sendKey(uint16_t key) {
26     uint8_t flags = mem_peek_byte(CE_graphFlags2);
27     if (flags & CE_keyReady) {
28         return false;
29     }
30     if (key < 0x100) {
31         key <<= 8;
32     }
33     mem_poke_byte(CE_kbdKey, (uint8_t)(key >> 8));
34     mem_poke_byte(CE_keyExtend, (uint8_t)(key & 0xFF));
35     mem_poke_byte(CE_graphFlags2, flags | CE_keyReady);
36     return true;
37 }
38 
sendLetterKeyPress(char letter)39 bool EMSCRIPTEN_KEEPALIVE sendLetterKeyPress(char letter) {
40     uint16_t key;
41     if (letter >= '0' && letter <= '9') {
42         key = 0x8E + letter - '0';
43     } else if (letter >= 'A' && letter <= 'Z') {
44         key = 0x9A + letter - 'A';
45     } else if (letter == 'Z' + 1 || letter == '@') { /* [ or @ for theta (caller should replace it) */
46         key = 0xCC;
47     } else {
48         return true;
49     }
50     return sendKey(key);
51 }
52