2 SHARP X1 Emulator 'eX1'
3 SHARP X1twin Emulator 'eX1twin'
4 SHARP X1turbo Emulator 'eX1turbo'
5 SHARP X1turboZ Emulator 'eX1turboZ'
7 Author : Takeda.Toshiya
14 #include "../datarec.h"
16 #include "../../fifo.h"
17 //#define DEBUG_COMMAND
21 #define EVENT_REPEAT 2
23 #define CMT_EJECT 0x00
26 #define CMT_FAST_FWD 0x03
27 #define CMT_FAST_REW 0x04
28 #define CMT_APSS_PLUS 0x05
29 #define CMT_APSS_MINUS 0x06
32 // TODO: XFER = 0xe8 ???
36 static const uint8_t keycode[256] = { // normal
37 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
39 0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
40 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
42 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
44 0x71, 0x72, 0x73, 0x74, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x3d, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x3b, 0x2c, 0x2d, 0x2e, 0x2f,
49 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x5c, 0x5d, 0x5e, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
54 static const uint8_t keycode_s[256] = { // shift
55 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
57 0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
58 0x30, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
60 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0x3c, 0x2d, 0x2e, 0x3f,
62 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x3c, 0x3d, 0x3e, 0x3f,
67 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x60, 0x00,
69 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
72 static const uint8_t keycode_g[256] = { // graph
73 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00,
75 0x00, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
76 0xfa, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x7f, 0x84, 0x82, 0xea, 0xe2, 0xeb, 0xec, 0xed, 0xe7, 0xee, 0xef, 0x8e, 0x86, 0x85, 0xf0,
78 0x8d, 0xe0, 0xe3, 0xe9, 0xe4, 0xe6, 0x83, 0xe1, 0x81, 0xe5, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x8f, 0x99, 0x92, 0x98, 0x95, 0x96, 0x94, 0x9a, 0x93, 0x97, 0x9b, 0x9d, 0x87, 0x9c, 0x91, 0x9e,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x89, 0x87, 0x8c, 0x88, 0xfe,
85 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfb, 0xe8, 0x8b, 0x00,
87 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
90 static const uint8_t keycode_c[256] = { // ctrl
91 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
92 0x1c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
93 0x00, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
94 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
96 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0x00, 0x2d, 0x2e, 0x2f,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xeb, 0xe2, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x3b, 0x00, 0x2d, 0x00, 0x00,
103 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x1c, 0x1d, 0x1e, 0x00,
105 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
108 static const uint8_t keycode_k[256] = { // kana
109 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
111 0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
112 0xdc, 0xc7, 0xcc, 0xb1, 0xb3, 0xb4, 0xb5, 0xd4, 0xd5, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0xc1, 0xba, 0xbf, 0xbc, 0xb2, 0xca, 0xb7, 0xb8, 0xc6, 0xcf, 0xc9, 0xd8, 0xd3, 0xd0, 0xd7,
114 0xbe, 0xc0, 0xbd, 0xc4, 0xb6, 0xc5, 0xcb, 0xc3, 0xbb, 0xdd, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xc8, 0x2d, 0x2e, 0xd2,
116 0x71, 0x72, 0x73, 0x74, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0xda, 0xc8, 0xce, 0xd9, 0xd2,
121 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xb0, 0xd1, 0xcd, 0x00,
123 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
126 static const uint8_t keycode_ks[256] = { // kana+shift
127 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
129 0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
130 0xa6, 0xc7, 0xcc, 0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0xc1, 0xba, 0xbf, 0xbc, 0xa8, 0xca, 0xb7, 0xb8, 0xc6, 0xcf, 0xc9, 0xd8, 0xd3, 0xd0, 0xd7,
132 0xbe, 0xc0, 0xbd, 0xc4, 0xb6, 0xc5, 0xcb, 0xc3, 0xbb, 0xdd, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xa4, 0x2d, 0x2e, 0xa5,
134 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0xda, 0xa4, 0xce, 0xa1, 0xa5,
139 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xb0, 0xa3, 0xcd, 0x00,
141 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
144 static const uint8_t keycode_kb[256] = { // kana (mode b)
145 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
147 0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
148 0xc9, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xc5, 0xc6, 0xc7, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0xbb, 0xc4, 0xc2, 0xbd, 0xb8, 0xbe, 0xbf, 0xcf, 0xcc, 0xd0, 0xd1, 0xd2, 0xd5, 0xd4, 0xcd,
150 0xce, 0xb6, 0xb9, 0xbc, 0xba, 0xcb, 0xc3, 0xb7, 0xc1, 0xca, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xc8, 0x2d, 0x2e, 0xd2,
152 0x71, 0x72, 0x73, 0x74, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xd3, 0xd6, 0xd7, 0xdc, 0xa6,
157 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xd9, 0xdf, 0xd8, 0x00,
159 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
162 static const uint8_t keycode_ksb[256] = { // kana+shift (mode b)
163 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
165 0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
166 0xc9, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xc5, 0xc6, 0xc7, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0xbb, 0xc4, 0xaf, 0xbd, 0xb8, 0xbe, 0xbf, 0xcf, 0xcc, 0xd0, 0xd1, 0xd2, 0xad, 0xac, 0xcd,
168 0xce, 0xb6, 0xb9, 0xbc, 0xba, 0xcb, 0xc3, 0xb7, 0xc1, 0xca, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xa4, 0x2d, 0x2e, 0xa5,
170 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xd3, 0xae, 0xd7, 0xa4, 0xa1,
175 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x20, 0xa3, 0xd8, 0x00,
177 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
181 void PSUB::initialize()
183 key_buf = new FIFO(8);
184 key_stat = emu->get_key_buffer();
186 get_host_time(&cur_time);
189 register_event(this, EVENT_1SEC, 1000000, true, &time_register_id);
190 register_event(this, EVENT_DRIVE, 400, true, NULL);
201 memset(databuf, 0, sizeof(databuf));
202 databuf[0x16][0] = 0xff;
203 datap = &databuf[0][0]; // temporary fix
205 cmdlen = datalen = 0;
207 play = rec = eot = false;
216 key_prev = key_break = 0;
217 key_shift = key_ctrl = key_graph = false;
218 key_caps_locked = key_kana_locked = false;
219 key_register_id = -1;
226 d_pio->write_signal(SIG_I8255_PORT_B, 0xff, 1);
229 void PSUB::write_io8(uint32_t addr, uint32_t data)
235 uint32_t PSUB::read_io8(uint32_t addr)
243 void PSUB::write_signal(int id, uint32_t data, uint32_t mask)
245 if(id == SIG_PSUB_TAPE_REMOTE) {
246 if(!(data & mask) && (play || rec)) {
247 databuf[0x1a][0] = CMT_STOP;
249 } else if(id == SIG_PSUB_TAPE_END) {
250 eot = ((data & mask) != 0);
254 void PSUB::set_intr_iei(bool val)
262 uint32_t PSUB::get_intr_ack()
264 return read_io8(0x1900);
267 void PSUB::notify_intr_reti()
269 // NOTE: some software uses RET, not RETI ???
272 void PSUB::update_intr()
275 d_cpu->set_intr_line(true, true, intr_bit);
277 d_cpu->set_intr_line(false, true, intr_bit);
280 #if defined(Q_OS_WIN)
281 DLL_PREFIX_I struct cur_time_s cur_time;
284 void PSUB::event_callback(int event_id, int err)
286 if(event_id == EVENT_1SEC) {
287 if(cur_time.initialized) {
288 cur_time.increment();
290 get_host_time(&cur_time); // resync
291 cur_time.initialized = true;
293 } else if(event_id == EVENT_DRIVE) {
295 static const int cmdlen_tbl[] = {
296 0, 1, 0, 0, 1, 0, 1, 0, 0, 3, 0, 3, 0
301 if(vm->is_cart_inserted(0)) {
307 // sub cpu received data from main cpu
309 // this is command parameter
312 this->out_debug_log(_T(" %2x"), inbuf);
316 // this is new command
319 this->out_debug_log(_T("X1 PSUB: cmd %2x"), inbuf);
321 if(0xd0 <= mode && mode <= 0xd7) {
323 datap = &databuf[mode - 0xd0][0]; // receive buffer
324 } else if(0xe3 <= mode && mode <= 0xef) {
325 cmdlen = cmdlen_tbl[mode - 0xe3];
326 datap = &databuf[mode - 0xd0][0]; // receive buffer
330 // this command has no parameters or all parameters are received,
331 // so cpu processes the command
333 this->out_debug_log(_T("\n"));
337 // sub cpu can accept new command or parameter
341 // if command is not finished, key irq is not raised
342 if(cmdlen || datalen) {
347 // sub cpu can send data to main cpu
349 // sub cpu sends result data
353 } else if(!key_buf->empty() && databuf[0x14][0] && !intr && iei) {
354 // key buffer is not empty and interrupt is not disabled,
355 // so sub cpu sends vector and raise irq
356 outbuf = databuf[0x14][0];
366 } else if(event_id == EVENT_REPEAT) {
367 key_register_id = -1;
368 key_down(key_prev, true);
372 // shift, ctrl, graph, caps, kana
373 #define IS_LOWBYTE_KEY(c) ((c >= 0x10 && c <= 0x12) || c == 0x14 || c == 0x15)
375 void PSUB::key_down(int code, bool repeat)
389 key_caps_locked = !key_caps_locked;
392 key_kana_locked = !key_kana_locked;
395 uint16_t lh = get_key(code, repeat);
398 if(!databuf[0x14][0]) {
404 // setup key repeat event
405 if(key_register_id != -1) {
406 cancel_event(this, key_register_id);
407 key_register_id = -1;
409 if(!(0x70 <= code && code <= 0x87)) {
411 register_event(this, EVENT_REPEAT, 61165, false, &key_register_id); // 61.165 msec
413 register_event(this, EVENT_REPEAT, 557085, false, &key_register_id); // 557.085 msec
417 // break key is pressed
419 d_pio->write_signal(SIG_I8255_PORT_B, 0, 1);
422 #ifdef _X1TURBO_FEATURE
423 } else if(key_prev == 0 && IS_LOWBYTE_KEY(code)) {
424 key_buf->write(0xff);
429 void PSUB::key_up(int code)
443 #ifdef _X1TURBO_FEATURE
444 if(code == key_prev || (key_prev == 0 && IS_LOWBYTE_KEY(code))) {
446 if(code == key_prev) {
448 // last pressed key is released
449 if(!databuf[0x14][0]) {
452 key_buf->write(0xff);
454 if(key_register_id != -1) {
455 cancel_event(this, key_register_id);
456 key_register_id = -1;
459 if(code == key_break) {
460 // break key is released
461 d_pio->write_signal(SIG_I8255_PORT_B, 0xff, 1);
466 void PSUB::play_tape(bool value)
469 databuf[0x1a][0] = CMT_STOP;
471 databuf[0x1a][0] = CMT_EJECT;
475 d_drec->set_remote(false);
478 void PSUB::rec_tape(bool value)
481 databuf[0x1a][0] = CMT_STOP;
483 databuf[0x1a][0] = CMT_EJECT;
487 d_drec->set_remote(false);
490 void PSUB::close_tape()
493 databuf[0x1a][0] = CMT_EJECT;
495 d_drec->set_remote(false);
499 void PSUB::process_cmd()
504 if(0xd0 <= mode && mode < 0xf0) {
505 datap = &databuf[mode - 0xd0][0]; // send buffer
512 // reset receive/send buffer
533 datap = &databuf[mode - 0xd8][0]; // data buffer for timer set
536 #ifdef _X1TURBO_FEATURE
538 // game key read (for turbo)
539 databuf[0x13][0] = databuf[0x13][1] = databuf[0x13][2] = 0;
540 if(config.keyboard_type != 0) {
541 databuf[0x13][0] |= key_stat[0x51] ? 0x80 : 0; // q
542 databuf[0x13][0] |= key_stat[0x57] ? 0x40 : 0; // w
543 databuf[0x13][0] |= key_stat[0x45] ? 0x20 : 0; // e
544 databuf[0x13][0] |= key_stat[0x41] ? 0x10 : 0; // a
545 databuf[0x13][0] |= key_stat[0x44] ? 0x08 : 0; // d
546 databuf[0x13][0] |= key_stat[0x5a] ? 0x04 : 0; // z
547 databuf[0x13][0] |= key_stat[0x58] ? 0x02 : 0; // x
548 databuf[0x13][0] |= key_stat[0x43] ? 0x01 : 0; // c
549 databuf[0x13][1] |= key_stat[0x67] ? 0x80 : 0; // 7
550 databuf[0x13][1] |= key_stat[0x64] ? 0x40 : 0; // 4
551 databuf[0x13][1] |= key_stat[0x61] ? 0x20 : 0; // 1
552 databuf[0x13][1] |= key_stat[0x68] ? 0x10 : 0; // 8
553 databuf[0x13][1] |= key_stat[0x62] ? 0x08 : 0; // 2
554 databuf[0x13][1] |= key_stat[0x69] ? 0x04 : 0; // 9
555 databuf[0x13][1] |= key_stat[0x66] ? 0x02 : 0; // 6
556 databuf[0x13][1] |= key_stat[0x63] ? 0x01 : 0; // 3
557 databuf[0x13][2] |= key_stat[0x1b] ? 0x80 : 0; // esc
558 databuf[0x13][2] |= key_stat[0x61] ? 0x40 : 0; // 1
559 databuf[0x13][2] |= key_stat[0x6d] ? 0x20 : 0; // -
560 databuf[0x13][2] |= key_stat[0x6b] ? 0x10 : 0; // +
561 databuf[0x13][2] |= key_stat[0x6a] ? 0x08 : 0; // *
562 databuf[0x13][2] |= key_stat[0x09] ? 0x04 : 0; // tab
563 databuf[0x13][2] |= key_stat[0x20] ? 0x02 : 0; // sp
564 databuf[0x13][2] |= key_stat[0x0d] ? 0x01 : 0; // ret
571 // if(!databuf[0x14][0]) {
572 while(!key_buf->empty()) {
573 lh = key_buf->read();
575 databuf[0x16][0] = lh & 0xff;
576 databuf[0x16][1] = lh >> 8;
584 if(!databuf[0x14][0]) {
585 // interrupt disabled
586 while(!key_buf->empty()) {
587 lh = key_buf->read();
588 databuf[0x16][0] = lh & 0xff;
589 databuf[0x16][1] = lh >> 8;
593 if(!key_buf->empty()) {
594 lh = key_buf->read();
595 databuf[0x16][0] = lh & 0xff;
596 databuf[0x16][1] = lh >> 8;
599 #ifdef _X1TURBO_FEATURE
600 databuf[0x16][0] &= ~0x1f;
601 databuf[0x16][0] |= get_key_low() & 0x1f;
604 this->out_debug_log(_T("X1 PSUB: keycode %2x %2x\n"), databuf[0x16][0], databuf[0x16][1]);
610 databuf[0x18][0] = databuf[0x17][0];
618 if(databuf[0x1a][0] != databuf[0x19][0]) {
619 uint8_t new_status = databuf[0x19][0];
620 switch(databuf[0x19][0]) {
625 d_drec->set_remote(false);
629 d_drec->set_ff_rew(0);
630 d_drec->set_remote(true);
632 new_status = CMT_STOP;
634 new_status = CMT_EJECT;
639 d_drec->set_ff_rew(1);
640 d_drec->set_remote(true);
642 new_status = CMT_STOP;
644 new_status = CMT_EJECT;
649 d_drec->set_ff_rew(-1);
650 d_drec->set_remote(true);
652 new_status = CMT_STOP;
654 new_status = CMT_EJECT;
660 d_drec->do_apss((databuf[0x19][0] == CMT_APSS_PLUS) ? 1 : -1);
661 new_status = CMT_STOP;
663 new_status = CMT_STOP;
665 new_status = CMT_EJECT;
670 new_status = CMT_STOP;
672 d_drec->set_remote(true);
674 new_status = CMT_EJECT;
679 this->out_debug_log(_T("X1 PSUB: unknown CMT control %2x\n"), databuf[0x19][0]);
684 databuf[0x1a][0] = new_status;
692 // CMT sensor (bit2=WP, bit1=SET, bit0=END)
693 databuf[0x1b][0] = (play ? 2 : rec ? 6 : 0) | (play && eot ? 1 : 0);
698 cur_time.year = FROM_BCD(databuf[0x1c][0]);
699 if((databuf[0x1c][1] & 0xf0) != 0) {
700 cur_time.month = databuf[0x1c][1] >> 4;
702 // cur_time.day_of_week = databuf[0x1c][1] & 7;
703 if(databuf[0x1c][2] != 0) {
704 cur_time.day = FROM_BCD(databuf[0x1c][2]);
706 cur_time.update_year();
707 cur_time.update_day_of_week();
711 databuf[0x1d][0] = TO_BCD(cur_time.year);
712 databuf[0x1d][1] = (cur_time.month << 4) | cur_time.day_of_week;
713 databuf[0x1d][2] = TO_BCD(cur_time.day);
718 cur_time.hour = FROM_BCD(databuf[0x1e][0]);
719 cur_time.minute = FROM_BCD(databuf[0x1e][1] & 0x7f);
720 cur_time.second = FROM_BCD(databuf[0x1e][2] & 0x7f);
722 cancel_event(this, time_register_id);
723 register_event(this, EVENT_1SEC, 1000000, true, &time_register_id);
727 databuf[0x1f][0] = TO_BCD(cur_time.hour);
728 databuf[0x1f][1] = TO_BCD(cur_time.minute);
729 databuf[0x1f][2] = TO_BCD(cur_time.second);
734 this->out_debug_log(_T("X1 PSUB: unknown cmd %2x\n"), mode);
739 void PSUB::set_ibf(bool val)
742 d_pio->write_signal(SIG_I8255_PORT_B, val ? 0xff : 0, 0x40);
747 void PSUB::set_obf(bool val)
750 d_pio->write_signal(SIG_I8255_PORT_B, val ? 0xff : 0, 0x20);
755 uint8_t PSUB::get_key_low()
765 if(key_kana_locked) {
768 if(key_caps_locked) {
772 l &= ~0x10; // graph (alt)
777 uint16_t PSUB::get_key(int code, bool repeat)
779 uint8_t l = get_key_low();
783 l &= ~0x20; // repeat
785 if(0x60 <= code && code <= 0x74) {
786 l &= ~0x80; // function or numpad
788 if(key_kana_locked) {
790 #ifdef _X1TURBO_FEATURE
791 if(config.keyboard_type != 0) {
792 h = keycode_ksb[code]; // kana+shift (mode b)
795 h = keycode_ks[code]; // kana+shift
797 #ifdef _X1TURBO_FEATURE
798 if(config.keyboard_type != 0) {
799 h = keycode_kb[code]; // kana (mode b)
802 h = keycode_k[code]; // kana
806 h = keycode_c[code]; // ctrl
807 } else if(!(l & 0x10)) {
808 h = keycode_g[code]; // graph
811 h = keycode_s[code]; // shift
813 h = keycode[code]; // (none shifted)
815 if(key_caps_locked) {
816 if(0x41 <= code && code <= 0x5a) {
817 h ^= 0x20; // alphabet
822 #ifndef _X1TURBO_FEATURE
830 #define STATE_VERSION 1
832 bool PSUB::process_state(FILEIO* state_fio, bool loading)
834 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
837 if(!state_fio->StateCheckInt32(this_device_id)) {
840 if(!cur_time.process_state((void *)state_fio, loading)) {
843 state_fio->StateValue(time_register_id);
844 state_fio->StateArray(&databuf[0][0], sizeof(databuf), 1);
846 intptr_t _d = (intptr_t)(&databuf[0][0]);
847 datap = (uint8_t*)(_d + state_fio->FgetInt32_LE());
849 intptr_t _d = (intptr_t)(&databuf[0][0]);
850 state_fio->FputInt32_LE((int)((intptr_t)datap - _d));
852 state_fio->StateValue(mode);
853 state_fio->StateValue(inbuf);
854 state_fio->StateValue(outbuf);
855 state_fio->StateValue(ibf);
856 state_fio->StateValue(obf);
857 state_fio->StateValue(cmdlen);
858 state_fio->StateValue(datalen);
859 if(!key_buf->process_state((void *)state_fio, loading)) {
862 state_fio->StateValue(key_prev);
863 state_fio->StateValue(key_break);
864 state_fio->StateValue(key_shift);
865 state_fio->StateValue(key_ctrl);
866 state_fio->StateValue(key_graph);
867 state_fio->StateValue(key_caps_locked);
868 state_fio->StateValue(key_kana_locked);
869 state_fio->StateValue(key_register_id);
870 state_fio->StateValue(play);
871 state_fio->StateValue(rec);
872 state_fio->StateValue(eot);
873 state_fio->StateValue(iei);
874 state_fio->StateValue(intr);
875 state_fio->StateValue(intr_bit);