2 SHARP X1 Emulator 'eX1'
3 SHARP X1twin Emulator 'eX1twin'
4 SHARP X1turbo Emulator 'eX1turbo'
6 Author : Takeda.Toshiya
13 #include "../datarec.h"
15 #include "../../fifo.h"
16 //#define DEBUG_COMMAND
20 #define EVENT_REPEAT 2
22 #define CMT_EJECT 0x00
25 #define CMT_FAST_FWD 0x03
26 #define CMT_FAST_REW 0x04
27 #define CMT_APSS_PLUS 0x05
28 #define CMT_APSS_MINUS 0x06
31 // TODO: XFER = 0xe8 ???
33 static const uint8_t keycode[256] = { // normal
34 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
36 0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
37 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
39 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
41 0x71, 0x72, 0x73, 0x74, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x3b, 0x2c, 0x2d, 0x2e, 0x2f,
46 0x40, 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, 0x5b, 0x5c, 0x5d, 0x5e, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
51 static const uint8_t keycode_s[256] = { // shift
52 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
54 0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
55 0x30, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
57 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0x3c, 0x2d, 0x2e, 0x3f,
59 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x3c, 0x3d, 0x3e, 0x3f,
64 0x7e, 0x00, 0x00, 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, 0x7b, 0x7c, 0x7d, 0x60, 0x00,
66 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
69 static const uint8_t keycode_g[256] = { // graph
70 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00,
72 0x00, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
73 0xfa, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x7f, 0x84, 0x82, 0xea, 0xe2, 0xeb, 0xec, 0xed, 0xe7, 0xee, 0xef, 0x8e, 0x86, 0x85, 0xf0,
75 0x8d, 0xe0, 0xe3, 0xe9, 0xe4, 0xe6, 0x83, 0xe1, 0x81, 0xe5, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x8f, 0x99, 0x92, 0x98, 0x95, 0x96, 0x94, 0x9a, 0x93, 0x97, 0x9b, 0x9d, 0x87, 0x9c, 0x91, 0x9e,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0xfd, 0x89, 0x87, 0x8c, 0x88, 0xfe,
82 0x8a, 0x00, 0x00, 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, 0xfc, 0xfb, 0xe8, 0x8b, 0x00,
84 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
87 static const uint8_t keycode_c[256] = { // ctrl
88 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
89 0x1c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
90 0x00, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
91 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
93 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0x00, 0x2d, 0x2e, 0x2f,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xeb, 0xe2, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x3b, 0x00, 0x2d, 0x00, 0x00,
100 0x40, 0x00, 0x00, 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, 0x1b, 0x1c, 0x1d, 0x1e, 0x00,
102 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
105 static const uint8_t keycode_k[256] = { // kana
106 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
108 0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
109 0xdc, 0xc7, 0xcc, 0xb1, 0xb3, 0xb4, 0xb5, 0xd4, 0xd5, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0xc1, 0xba, 0xbf, 0xbc, 0xb2, 0xca, 0xb7, 0xb8, 0xc6, 0xcf, 0xc9, 0xd8, 0xd3, 0xd0, 0xd7,
111 0xbe, 0xc0, 0xbd, 0xc4, 0xb6, 0xc5, 0xcb, 0xc3, 0xbb, 0xdd, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xc8, 0x2d, 0x2e, 0xd2,
113 0x71, 0x72, 0x73, 0x74, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0xda, 0xc8, 0xce, 0xd9, 0xd2,
118 0xde, 0x00, 0x00, 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, 0xdf, 0xb0, 0xd1, 0xcd, 0x00,
120 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
123 static const uint8_t keycode_ks[256] = { // kana+shift
124 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
126 0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
127 0xa6, 0xc7, 0xcc, 0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0xc1, 0xba, 0xbf, 0xbc, 0xa8, 0xca, 0xb7, 0xb8, 0xc6, 0xcf, 0xc9, 0xd8, 0xd3, 0xd0, 0xd7,
129 0xbe, 0xc0, 0xbd, 0xc4, 0xb6, 0xc5, 0xcb, 0xc3, 0xbb, 0xdd, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xa4, 0x2d, 0x2e, 0xa5,
131 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0xda, 0xa4, 0xce, 0xa1, 0xa5,
136 0xde, 0x00, 0x00, 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, 0xa2, 0xb0, 0xa3, 0xcd, 0x00,
138 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
141 static const uint8_t keycode_kb[256] = { // kana (mode b)
142 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
144 0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
145 0xc9, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xc5, 0xc6, 0xc7, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0xbb, 0xc4, 0xc2, 0xbd, 0xb8, 0xbe, 0xbf, 0xcf, 0xcc, 0xd0, 0xd1, 0xd2, 0xd5, 0xd4, 0xcd,
147 0xce, 0xb6, 0xb9, 0xbc, 0xba, 0xcb, 0xc3, 0xb7, 0xc1, 0xca, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xc8, 0x2d, 0x2e, 0xd2,
149 0x71, 0x72, 0x73, 0x74, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xd3, 0xd6, 0xd7, 0xdc, 0xa6,
154 0xda, 0x00, 0x00, 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, 0xdb, 0xd9, 0xdf, 0xd8, 0x00,
156 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
159 static const uint8_t keycode_ksb[256] = { // kana+shift (mode b)
160 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
162 0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
163 0xc9, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xc5, 0xc6, 0xc7, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 0x00, 0xbb, 0xc4, 0xaf, 0xbd, 0xb8, 0xbe, 0xbf, 0xcf, 0xcc, 0xd0, 0xd1, 0xd2, 0xad, 0xac, 0xcd,
165 0xce, 0xb6, 0xb9, 0xbc, 0xba, 0xcb, 0xc3, 0xb7, 0xc1, 0xca, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xa4, 0x2d, 0x2e, 0xa5,
167 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xd3, 0xae, 0xd7, 0xa4, 0xa1,
172 0xda, 0x00, 0x00, 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, 0xa2, 0x20, 0xa3, 0xd8, 0x00,
174 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
178 void PSUB::initialize()
180 key_buf = new FIFO(8);
181 key_stat = emu->get_key_buffer();
183 get_host_time(&cur_time);
186 register_event(this, EVENT_1SEC, 1000000, true, &time_register_id);
187 register_event(this, EVENT_DRIVE, 400, true, NULL);
198 memset(databuf, 0, sizeof(databuf));
199 databuf[0x16][0] = 0xff;
200 datap = &databuf[0][0]; // temporary fix
202 cmdlen = datalen = 0;
204 play = rec = eot = false;
213 key_prev = key_break = 0;
214 key_shift = key_ctrl = key_graph = false;
215 key_caps_locked = key_kana_locked = false;
216 key_register_id = -1;
223 d_pio->write_signal(SIG_I8255_PORT_B, 0xff, 1);
226 void PSUB::write_io8(uint32_t addr, uint32_t data)
232 uint32_t PSUB::read_io8(uint32_t addr)
240 void PSUB::write_signal(int id, uint32_t data, uint32_t mask)
242 if(id == SIG_PSUB_TAPE_REMOTE) {
243 if(!(data & mask) && (play || rec)) {
244 databuf[0x1a][0] = CMT_STOP;
246 } else if(id == SIG_PSUB_TAPE_END) {
247 eot = ((data & mask) != 0);
251 void PSUB::set_intr_iei(bool val)
259 uint32_t PSUB::get_intr_ack()
261 return read_io8(0x1900);
264 void PSUB::notify_intr_reti()
266 // NOTE: some software uses RET, not RETI ???
269 void PSUB::update_intr()
272 d_cpu->set_intr_line(true, true, intr_bit);
274 d_cpu->set_intr_line(false, true, intr_bit);
277 #if defined(Q_OS_WIN)
278 DLL_PREFIX_I struct cur_time_s cur_time;
281 void PSUB::event_callback(int event_id, int err)
283 if(event_id == EVENT_1SEC) {
284 if(cur_time.initialized) {
285 cur_time.increment();
287 get_host_time(&cur_time); // resync
288 cur_time.initialized = true;
290 } else if(event_id == EVENT_DRIVE) {
292 static const int cmdlen_tbl[] = {
293 0, 1, 0, 0, 1, 0, 1, 0, 0, 3, 0, 3, 0
298 if(vm->is_cart_inserted(0)) {
304 // sub cpu received data from main cpu
306 // this is command parameter
309 this->out_debug_log(_T(" %2x"), inbuf);
313 // this is new command
316 this->out_debug_log(_T("X1 PSUB: cmd %2x"), inbuf);
318 if(0xd0 <= mode && mode <= 0xd7) {
320 datap = &databuf[mode - 0xd0][0]; // receive buffer
321 } else if(0xe3 <= mode && mode <= 0xef) {
322 cmdlen = cmdlen_tbl[mode - 0xe3];
323 datap = &databuf[mode - 0xd0][0]; // receive buffer
327 // this command has no parameters or all parameters are received,
328 // so cpu processes the command
330 this->out_debug_log(_T("\n"));
334 // sub cpu can accept new command or parameter
338 // if command is not finished, key irq is not raised
339 if(cmdlen || datalen) {
344 // sub cpu can send data to main cpu
346 // sub cpu sends result data
350 } else if(!key_buf->empty() && databuf[0x14][0] && !intr && iei) {
351 // key buffer is not empty and interrupt is not disabled,
352 // so sub cpu sends vector and raise irq
353 outbuf = databuf[0x14][0];
363 } else if(event_id == EVENT_REPEAT) {
364 key_register_id = -1;
365 key_down(key_prev, true);
369 // shift, ctrl, graph, caps, kana
370 #define IS_LOWBYTE_KEY(c) ((c >= 0x10 && c <= 0x12) || c == 0x14 || c == 0x15)
372 void PSUB::key_down(int code, bool repeat)
386 key_caps_locked = !key_caps_locked;
389 key_kana_locked = !key_kana_locked;
392 uint16_t lh = get_key(code, repeat);
395 if(!databuf[0x14][0]) {
401 // setup key repeat event
402 if(key_register_id != -1) {
403 cancel_event(this, key_register_id);
404 key_register_id = -1;
406 if(!(0x70 <= code && code <= 0x87)) {
408 register_event(this, EVENT_REPEAT, 61165, false, &key_register_id); // 61.165 msec
410 register_event(this, EVENT_REPEAT, 557085, false, &key_register_id); // 557.085 msec
414 // break key is pressed
416 d_pio->write_signal(SIG_I8255_PORT_B, 0, 1);
419 #ifdef _X1TURBO_FEATURE
420 } else if(key_prev == 0 && IS_LOWBYTE_KEY(code)) {
421 key_buf->write(0xff);
426 void PSUB::key_up(int code)
440 #ifdef _X1TURBO_FEATURE
441 if(code == key_prev || (key_prev == 0 && IS_LOWBYTE_KEY(code))) {
443 if(code == key_prev) {
445 // last pressed key is released
446 if(!databuf[0x14][0]) {
449 key_buf->write(0xff);
451 if(key_register_id != -1) {
452 cancel_event(this, key_register_id);
453 key_register_id = -1;
456 if(code == key_break) {
457 // break key is released
458 d_pio->write_signal(SIG_I8255_PORT_B, 0xff, 1);
463 void PSUB::play_tape(bool value)
466 databuf[0x1a][0] = CMT_STOP;
468 databuf[0x1a][0] = CMT_EJECT;
472 d_drec->set_remote(false);
475 void PSUB::rec_tape(bool value)
478 databuf[0x1a][0] = CMT_STOP;
480 databuf[0x1a][0] = CMT_EJECT;
484 d_drec->set_remote(false);
487 void PSUB::close_tape()
490 databuf[0x1a][0] = CMT_EJECT;
492 d_drec->set_remote(false);
496 void PSUB::process_cmd()
501 if(0xd0 <= mode && mode < 0xf0) {
502 datap = &databuf[mode - 0xd0][0]; // send buffer
509 // reset receive/send buffer
530 datap = &databuf[mode - 0xd8][0]; // data buffer for timer set
533 #ifdef _X1TURBO_FEATURE
535 // game key read (for turbo)
536 databuf[0x13][0] = databuf[0x13][1] = databuf[0x13][2] = 0;
537 if(config.keyboard_type != 0) {
538 databuf[0x13][0] |= key_stat[0x51] ? 0x80 : 0; // q
539 databuf[0x13][0] |= key_stat[0x57] ? 0x40 : 0; // w
540 databuf[0x13][0] |= key_stat[0x45] ? 0x20 : 0; // e
541 databuf[0x13][0] |= key_stat[0x41] ? 0x10 : 0; // a
542 databuf[0x13][0] |= key_stat[0x44] ? 0x08 : 0; // d
543 databuf[0x13][0] |= key_stat[0x5a] ? 0x04 : 0; // z
544 databuf[0x13][0] |= key_stat[0x58] ? 0x02 : 0; // x
545 databuf[0x13][0] |= key_stat[0x43] ? 0x01 : 0; // c
546 databuf[0x13][1] |= key_stat[0x67] ? 0x80 : 0; // 7
547 databuf[0x13][1] |= key_stat[0x64] ? 0x40 : 0; // 4
548 databuf[0x13][1] |= key_stat[0x61] ? 0x20 : 0; // 1
549 databuf[0x13][1] |= key_stat[0x68] ? 0x10 : 0; // 8
550 databuf[0x13][1] |= key_stat[0x62] ? 0x08 : 0; // 2
551 databuf[0x13][1] |= key_stat[0x69] ? 0x04 : 0; // 9
552 databuf[0x13][1] |= key_stat[0x66] ? 0x02 : 0; // 6
553 databuf[0x13][1] |= key_stat[0x63] ? 0x01 : 0; // 3
554 databuf[0x13][2] |= key_stat[0x1b] ? 0x80 : 0; // esc
555 databuf[0x13][2] |= key_stat[0x61] ? 0x40 : 0; // 1
556 databuf[0x13][2] |= key_stat[0x6d] ? 0x20 : 0; // -
557 databuf[0x13][2] |= key_stat[0x6b] ? 0x10 : 0; // +
558 databuf[0x13][2] |= key_stat[0x6a] ? 0x08 : 0; // *
559 databuf[0x13][2] |= key_stat[0x09] ? 0x04 : 0; // tab
560 databuf[0x13][2] |= key_stat[0x20] ? 0x02 : 0; // sp
561 databuf[0x13][2] |= key_stat[0x0d] ? 0x01 : 0; // ret
568 // if(!databuf[0x14][0]) {
569 while(!key_buf->empty()) {
570 lh = key_buf->read();
572 databuf[0x16][0] = lh & 0xff;
573 databuf[0x16][1] = lh >> 8;
581 if(!databuf[0x14][0]) {
582 // interrupt disabled
583 while(!key_buf->empty()) {
584 lh = key_buf->read();
585 databuf[0x16][0] = lh & 0xff;
586 databuf[0x16][1] = lh >> 8;
590 if(!key_buf->empty()) {
591 lh = key_buf->read();
592 databuf[0x16][0] = lh & 0xff;
593 databuf[0x16][1] = lh >> 8;
596 #ifdef _X1TURBO_FEATURE
597 databuf[0x16][0] &= ~0x1f;
598 databuf[0x16][0] |= get_key_low() & 0x1f;
601 this->out_debug_log(_T("X1 PSUB: keycode %2x %2x\n"), databuf[0x16][0], databuf[0x16][1]);
607 databuf[0x18][0] = databuf[0x17][0];
615 if(databuf[0x1a][0] != databuf[0x19][0]) {
616 uint8_t new_status = databuf[0x19][0];
617 switch(databuf[0x19][0]) {
622 d_drec->set_remote(false);
626 d_drec->set_ff_rew(0);
627 d_drec->set_remote(true);
629 new_status = CMT_STOP;
631 new_status = CMT_EJECT;
636 d_drec->set_ff_rew(1);
637 d_drec->set_remote(true);
639 new_status = CMT_STOP;
641 new_status = CMT_EJECT;
646 d_drec->set_ff_rew(-1);
647 d_drec->set_remote(true);
649 new_status = CMT_STOP;
651 new_status = CMT_EJECT;
657 d_drec->do_apss((databuf[0x19][0] == CMT_APSS_PLUS) ? 1 : -1);
658 new_status = CMT_STOP;
660 new_status = CMT_STOP;
662 new_status = CMT_EJECT;
667 new_status = CMT_STOP;
669 d_drec->set_remote(true);
671 new_status = CMT_EJECT;
676 this->out_debug_log(_T("X1 PSUB: unknown CMT control %2x\n"), databuf[0x19][0]);
681 databuf[0x1a][0] = new_status;
689 // CMT sensor (bit2=WP, bit1=SET, bit0=END)
690 databuf[0x1b][0] = (play ? 2 : rec ? 6 : 0) | (play && eot ? 1 : 0);
695 cur_time.year = FROM_BCD(databuf[0x1c][0]);
696 if((databuf[0x1c][1] & 0xf0) != 0) {
697 cur_time.month = databuf[0x1c][1] >> 4;
699 // cur_time.day_of_week = databuf[0x1c][1] & 7;
700 if(databuf[0x1c][2] != 0) {
701 cur_time.day = FROM_BCD(databuf[0x1c][2]);
703 cur_time.update_year();
704 cur_time.update_day_of_week();
708 databuf[0x1d][0] = TO_BCD(cur_time.year);
709 databuf[0x1d][1] = (cur_time.month << 4) | cur_time.day_of_week;
710 databuf[0x1d][2] = TO_BCD(cur_time.day);
715 cur_time.hour = FROM_BCD(databuf[0x1e][0]);
716 cur_time.minute = FROM_BCD(databuf[0x1e][1] & 0x7f);
717 cur_time.second = FROM_BCD(databuf[0x1e][2] & 0x7f);
719 cancel_event(this, time_register_id);
720 register_event(this, EVENT_1SEC, 1000000, true, &time_register_id);
724 databuf[0x1f][0] = TO_BCD(cur_time.hour);
725 databuf[0x1f][1] = TO_BCD(cur_time.minute);
726 databuf[0x1f][2] = TO_BCD(cur_time.second);
731 this->out_debug_log(_T("X1 PSUB: unknown cmd %2x\n"), mode);
736 void PSUB::set_ibf(bool val)
739 d_pio->write_signal(SIG_I8255_PORT_B, val ? 0xff : 0, 0x40);
744 void PSUB::set_obf(bool val)
747 d_pio->write_signal(SIG_I8255_PORT_B, val ? 0xff : 0, 0x20);
752 uint8_t PSUB::get_key_low()
762 if(key_kana_locked) {
765 if(key_caps_locked) {
769 l &= ~0x10; // graph (alt)
774 uint16_t PSUB::get_key(int code, bool repeat)
776 uint8_t l = get_key_low();
780 l &= ~0x20; // repeat
782 if(0x60 <= code && code <= 0x74) {
783 l &= ~0x80; // function or numpad
785 if(key_kana_locked) {
787 #ifdef _X1TURBO_FEATURE
788 if(config.keyboard_type != 0) {
789 h = keycode_ksb[code]; // kana+shift (mode b)
792 h = keycode_ks[code]; // kana+shift
794 #ifdef _X1TURBO_FEATURE
795 if(config.keyboard_type != 0) {
796 h = keycode_kb[code]; // kana (mode b)
799 h = keycode_k[code]; // kana
803 h = keycode_c[code]; // ctrl
804 } else if(!(l & 0x10)) {
805 h = keycode_g[code]; // graph
808 h = keycode_s[code]; // shift
810 h = keycode[code]; // (none shifted)
812 if(key_caps_locked) {
813 if(0x41 <= code && code <= 0x5a) {
814 h ^= 0x20; // alphabet
819 #ifndef _X1TURBO_FEATURE
827 #define STATE_VERSION 1
829 void PSUB::save_state(FILEIO* state_fio)
831 state_fio->FputUint32(STATE_VERSION);
832 state_fio->FputInt32(this_device_id);
834 cur_time.save_state((void *)state_fio);
835 state_fio->FputInt32(time_register_id);
836 state_fio->Fwrite(databuf, sizeof(databuf), 1);
837 state_fio->FputInt32((int)(datap - &databuf[0][0]));
838 state_fio->FputUint8(mode);
839 state_fio->FputUint8(inbuf);
840 state_fio->FputUint8(outbuf);
841 state_fio->FputBool(ibf);
842 state_fio->FputBool(obf);
843 state_fio->FputInt32(cmdlen);
844 state_fio->FputInt32(datalen);
845 key_buf->save_state((void *)state_fio);
846 state_fio->FputInt32(key_prev);
847 state_fio->FputInt32(key_break);
848 state_fio->FputBool(key_shift);
849 state_fio->FputBool(key_ctrl);
850 state_fio->FputBool(key_graph);
851 state_fio->FputBool(key_caps_locked);
852 state_fio->FputBool(key_kana_locked);
853 state_fio->FputInt32(key_register_id);
854 state_fio->FputBool(play);
855 state_fio->FputBool(rec);
856 state_fio->FputBool(eot);
857 state_fio->FputBool(iei);
858 state_fio->FputBool(intr);
859 state_fio->FputUint32(intr_bit);
862 bool PSUB::load_state(FILEIO* state_fio)
864 if(state_fio->FgetUint32() != STATE_VERSION) {
867 if(state_fio->FgetInt32() != this_device_id) {
870 if(!cur_time.load_state((void *)state_fio)) {
873 time_register_id = state_fio->FgetInt32();
874 state_fio->Fread(databuf, sizeof(databuf), 1);
875 datap = &databuf[0][0] + state_fio->FgetInt32();
876 mode = state_fio->FgetUint8();
877 inbuf = state_fio->FgetUint8();
878 outbuf = state_fio->FgetUint8();
879 ibf = state_fio->FgetBool();
880 obf = state_fio->FgetBool();
881 cmdlen = state_fio->FgetInt32();
882 datalen = state_fio->FgetInt32();
883 if(!key_buf->load_state((void *)state_fio)) {
886 key_prev = state_fio->FgetInt32();
887 key_break = state_fio->FgetInt32();
888 key_shift = state_fio->FgetBool();
889 key_ctrl = state_fio->FgetBool();
890 key_graph = state_fio->FgetBool();
891 key_caps_locked = state_fio->FgetBool();
892 key_kana_locked = state_fio->FgetBool();
893 key_register_id = state_fio->FgetInt32();
894 play = state_fio->FgetBool();
895 rec = state_fio->FgetBool();
896 eot = state_fio->FgetBool();
897 iei = state_fio->FgetBool();
898 intr = state_fio->FgetBool();
899 intr_bit = state_fio->FgetUint32();