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"
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 ???
34 static const uint8_t keycode[256] = { // normal
35 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
36 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
37 0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
38 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
40 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
42 0x71, 0x72, 0x73, 0x74, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x3d, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x3b, 0x2c, 0x2d, 0x2e, 0x2f,
47 0x40, 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, 0x00, 0x5b, 0x5c, 0x5d, 0x5e, 0x00,
49 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00
52 static const uint8_t keycode_s[256] = { // shift
53 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
55 0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
56 0x30, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
58 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0x3c, 0x2d, 0x2e, 0x3f,
60 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x3d, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x3c, 0x3d, 0x3e, 0x3f,
65 0x7e, 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, 0x00, 0x7b, 0x7c, 0x7d, 0x60, 0x00,
67 0x00, 0x00, 0x5f, 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, 0x00, 0x00, 0x00, 0x00, 0x00
70 static const uint8_t keycode_g[256] = { // graph
71 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00,
73 0x00, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
74 0xfa, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x7f, 0x84, 0x82, 0xea, 0xe2, 0xeb, 0xec, 0xed, 0xe7, 0xee, 0xef, 0x8e, 0x86, 0x85, 0xf0,
76 0x8d, 0xe0, 0xe3, 0xe9, 0xe4, 0xe6, 0x83, 0xe1, 0x81, 0xe5, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x8f, 0x99, 0x92, 0x98, 0x95, 0x96, 0x94, 0x9a, 0x93, 0x97, 0x9b, 0x9d, 0x87, 0x9c, 0x91, 0x9e,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x90, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x89, 0x87, 0x8c, 0x88, 0xfe,
83 0x8a, 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, 0x00, 0xfc, 0xfb, 0xe8, 0x8b, 0x00,
85 0x00, 0x00, 0xff, 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, 0x00, 0x00, 0x00, 0x00, 0x00
88 static const uint8_t keycode_c[256] = { // ctrl
89 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
90 0x1c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
91 0x00, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
92 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
94 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0x00, 0x2d, 0x2e, 0x2f,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xeb, 0xe2, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x3b, 0x00, 0x2d, 0x00, 0x00,
101 0x40, 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, 0x00, 0x1b, 0x1c, 0x1d, 0x1e, 0x00,
103 0x00, 0x00, 0x1f, 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, 0x00, 0x00, 0x00, 0x00, 0x00
106 static const uint8_t keycode_k[256] = { // kana
107 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
109 0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
110 0xdc, 0xc7, 0xcc, 0xb1, 0xb3, 0xb4, 0xb5, 0xd4, 0xd5, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0xc1, 0xba, 0xbf, 0xbc, 0xb2, 0xca, 0xb7, 0xb8, 0xc6, 0xcf, 0xc9, 0xd8, 0xd3, 0xd0, 0xd7,
112 0xbe, 0xc0, 0xbd, 0xc4, 0xb6, 0xc5, 0xcb, 0xc3, 0xbb, 0xdd, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xc8, 0x2d, 0x2e, 0xd2,
114 0x71, 0x72, 0x73, 0x74, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x3d, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0xda, 0xc8, 0xce, 0xd9, 0xd2,
119 0xde, 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, 0x00, 0xdf, 0xb0, 0xd1, 0xcd, 0x00,
121 0x00, 0x00, 0xdb, 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, 0x00, 0x00, 0x00, 0x00, 0x00
124 static const uint8_t keycode_ks[256] = { // kana+shift
125 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
127 0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
128 0xa6, 0xc7, 0xcc, 0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0xc1, 0xba, 0xbf, 0xbc, 0xa8, 0xca, 0xb7, 0xb8, 0xc6, 0xcf, 0xc9, 0xd8, 0xd3, 0xd0, 0xd7,
130 0xbe, 0xc0, 0xbd, 0xc4, 0xb6, 0xc5, 0xcb, 0xc3, 0xbb, 0xdd, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xa4, 0x2d, 0x2e, 0xa5,
132 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x3d, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0xda, 0xa4, 0xce, 0xa1, 0xa5,
137 0xde, 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, 0x00, 0xa2, 0xb0, 0xa3, 0xcd, 0x00,
139 0x00, 0x00, 0xdb, 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, 0x00, 0x00, 0x00, 0x00, 0x00
142 static const uint8_t keycode_kb[256] = { // kana (mode b)
143 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
145 0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
146 0xc9, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xc5, 0xc6, 0xc7, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0xbb, 0xc4, 0xc2, 0xbd, 0xb8, 0xbe, 0xbf, 0xcf, 0xcc, 0xd0, 0xd1, 0xd2, 0xd5, 0xd4, 0xcd,
148 0xce, 0xb6, 0xb9, 0xbc, 0xba, 0xcb, 0xc3, 0xb7, 0xc1, 0xca, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xc8, 0x2d, 0x2e, 0xd2,
150 0x71, 0x72, 0x73, 0x74, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x3d, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xd3, 0xd6, 0xd7, 0xdc, 0xa6,
155 0xda, 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, 0x00, 0xdb, 0xd9, 0xdf, 0xd8, 0x00,
157 0x00, 0x00, 0xdd, 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, 0x00, 0x00, 0x00, 0x00, 0x00
160 static const uint8_t keycode_ksb[256] = { // kana+shift (mode b)
161 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
163 0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
164 0xc9, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xc5, 0xc6, 0xc7, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x00, 0xbb, 0xc4, 0xaf, 0xbd, 0xb8, 0xbe, 0xbf, 0xcf, 0xcc, 0xd0, 0xd1, 0xd2, 0xad, 0xac, 0xcd,
166 0xce, 0xb6, 0xb9, 0xbc, 0xba, 0xcb, 0xc3, 0xb7, 0xc1, 0xca, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xa4, 0x2d, 0x2e, 0xa5,
168 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x3d, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xd3, 0xae, 0xd7, 0xa4, 0xa1,
173 0xda, 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, 0x00, 0xa2, 0x20, 0xa3, 0xd8, 0x00,
175 0x00, 0x00, 0xa5, 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, 0x00, 0x00, 0x00, 0x00, 0x00
179 void PSUB::initialize()
181 key_buf = new FIFO(8);
182 key_stat = emu->get_key_buffer();
184 get_host_time(&cur_time);
187 register_event(this, EVENT_1SEC, 1000000, true, &time_register_id);
188 register_event(this, EVENT_DRIVE, 400, true, NULL);
199 memset(databuf, 0, sizeof(databuf));
200 databuf[0x16][0] = 0xff;
201 datap = &databuf[0][0]; // temporary fix
203 cmdlen = datalen = 0;
205 play = rec = eot = false;
214 key_prev = key_break = 0;
215 key_shift = key_ctrl = key_graph = false;
216 key_caps_locked = key_kana_locked = false;
217 key_register_id = -1;
224 d_pio->write_signal(SIG_I8255_PORT_B, 0xff, 1);
227 void PSUB::write_io8(uint32_t addr, uint32_t data)
233 uint32_t PSUB::read_io8(uint32_t addr)
241 void PSUB::write_signal(int id, uint32_t data, uint32_t mask)
243 if(id == SIG_PSUB_TAPE_REMOTE) {
244 if(!(data & mask) && (play || rec)) {
245 databuf[0x1a][0] = CMT_STOP;
247 } else if(id == SIG_PSUB_TAPE_END) {
248 eot = ((data & mask) != 0);
252 void PSUB::set_intr_iei(bool val)
260 uint32_t PSUB::get_intr_ack()
262 return read_io8(0x1900);
265 void PSUB::notify_intr_reti()
267 // NOTE: some software uses RET, not RETI ???
270 void PSUB::update_intr()
273 d_cpu->set_intr_line(true, true, intr_bit);
275 d_cpu->set_intr_line(false, true, intr_bit);
279 void PSUB::event_callback(int event_id, int err)
281 if(event_id == EVENT_1SEC) {
282 if(cur_time.initialized) {
283 cur_time.increment();
285 get_host_time(&cur_time); // resync
286 cur_time.initialized = true;
288 } else if(event_id == EVENT_DRIVE) {
290 static const int cmdlen_tbl[] = {
291 0, 1, 0, 0, 1, 0, 1, 0, 0, 3, 0, 3, 0
296 if(vm->is_cart_inserted(0)) {
302 // sub cpu received data from main cpu
304 // this is command parameter
307 this->out_debug_log(_T(" %2x"), inbuf);
311 // this is new command
314 this->out_debug_log(_T("X1 PSUB: cmd %2x"), inbuf);
316 if(0xd0 <= mode && mode <= 0xd7) {
318 datap = &databuf[mode - 0xd0][0]; // receive buffer
319 } else if(0xe3 <= mode && mode <= 0xef) {
320 cmdlen = cmdlen_tbl[mode - 0xe3];
321 datap = &databuf[mode - 0xd0][0]; // receive buffer
325 // this command has no parameters or all parameters are received,
326 // so cpu processes the command
328 this->out_debug_log(_T("\n"));
332 // sub cpu can accept new command or parameter
336 // if command is not finished, key irq is not raised
337 if(cmdlen || datalen) {
342 // sub cpu can send data to main cpu
344 // sub cpu sends result data
348 } else if(!key_buf->empty() && databuf[0x14][0] && !intr && iei) {
349 // key buffer is not empty and interrupt is not disabled,
350 // so sub cpu sends vector and raise irq
351 outbuf = databuf[0x14][0];
361 } else if(event_id == EVENT_REPEAT) {
362 key_register_id = -1;
363 key_down(key_prev, true);
367 // shift, ctrl, graph, caps, kana
368 #define IS_LOWBYTE_KEY(c) ((c >= 0x10 && c <= 0x12) || c == 0x14 || c == 0x15)
370 void PSUB::key_down(int code, bool repeat)
384 key_caps_locked = !key_caps_locked;
387 key_kana_locked = !key_kana_locked;
390 uint16_t lh = get_key(code, repeat);
393 if(!databuf[0x14][0]) {
399 // setup key repeat event
400 if(key_register_id != -1) {
401 cancel_event(this, key_register_id);
402 key_register_id = -1;
404 if(!(0x70 <= code && code <= 0x87)) {
406 register_event(this, EVENT_REPEAT, 61165, false, &key_register_id); // 61.165 msec
408 register_event(this, EVENT_REPEAT, 557085, false, &key_register_id); // 557.085 msec
412 // break key is pressed
414 d_pio->write_signal(SIG_I8255_PORT_B, 0, 1);
417 #ifdef _X1TURBO_FEATURE
418 } else if(key_prev == 0 && IS_LOWBYTE_KEY(code)) {
419 key_buf->write(0xff);
424 void PSUB::key_up(int code)
438 #ifdef _X1TURBO_FEATURE
439 if(code == key_prev || (key_prev == 0 && IS_LOWBYTE_KEY(code))) {
441 if(code == key_prev) {
443 // last pressed key is released
444 if(!databuf[0x14][0]) {
447 key_buf->write(0xff);
449 if(key_register_id != -1) {
450 cancel_event(this, key_register_id);
451 key_register_id = -1;
454 if(code == key_break) {
455 // break key is released
456 d_pio->write_signal(SIG_I8255_PORT_B, 0xff, 1);
461 void PSUB::play_tape(bool value)
464 databuf[0x1a][0] = CMT_STOP;
466 databuf[0x1a][0] = CMT_EJECT;
470 d_drec->set_remote(false);
473 void PSUB::rec_tape(bool value)
476 databuf[0x1a][0] = CMT_STOP;
478 databuf[0x1a][0] = CMT_EJECT;
482 d_drec->set_remote(false);
485 void PSUB::close_tape()
488 databuf[0x1a][0] = CMT_EJECT;
490 d_drec->set_remote(false);
494 void PSUB::process_cmd()
499 if(0xd0 <= mode && mode < 0xf0) {
500 datap = &databuf[mode - 0xd0][0]; // send buffer
507 // reset receive/send buffer
528 datap = &databuf[mode - 0xd8][0]; // data buffer for timer set
531 #ifdef _X1TURBO_FEATURE
533 // game key read (for turbo)
534 databuf[0x13][0] = databuf[0x13][1] = databuf[0x13][2] = 0;
535 if(config.device_type != 0) {
536 databuf[0x13][0] |= key_stat[0x51] ? 0x80 : 0; // q
537 databuf[0x13][0] |= key_stat[0x57] ? 0x40 : 0; // w
538 databuf[0x13][0] |= key_stat[0x45] ? 0x20 : 0; // e
539 databuf[0x13][0] |= key_stat[0x41] ? 0x10 : 0; // a
540 databuf[0x13][0] |= key_stat[0x44] ? 0x08 : 0; // d
541 databuf[0x13][0] |= key_stat[0x5a] ? 0x04 : 0; // z
542 databuf[0x13][0] |= key_stat[0x58] ? 0x02 : 0; // x
543 databuf[0x13][0] |= key_stat[0x43] ? 0x01 : 0; // c
544 databuf[0x13][1] |= key_stat[0x67] ? 0x80 : 0; // 7
545 databuf[0x13][1] |= key_stat[0x64] ? 0x40 : 0; // 4
546 databuf[0x13][1] |= key_stat[0x61] ? 0x20 : 0; // 1
547 databuf[0x13][1] |= key_stat[0x68] ? 0x10 : 0; // 8
548 databuf[0x13][1] |= key_stat[0x62] ? 0x08 : 0; // 2
549 databuf[0x13][1] |= key_stat[0x69] ? 0x04 : 0; // 9
550 databuf[0x13][1] |= key_stat[0x66] ? 0x02 : 0; // 6
551 databuf[0x13][1] |= key_stat[0x63] ? 0x01 : 0; // 3
552 databuf[0x13][2] |= key_stat[0x1b] ? 0x80 : 0; // esc
553 databuf[0x13][2] |= key_stat[0x61] ? 0x40 : 0; // 1
554 databuf[0x13][2] |= key_stat[0x6d] ? 0x20 : 0; // -
555 databuf[0x13][2] |= key_stat[0x6b] ? 0x10 : 0; // +
556 databuf[0x13][2] |= key_stat[0x6a] ? 0x08 : 0; // *
557 databuf[0x13][2] |= key_stat[0x09] ? 0x04 : 0; // tab
558 databuf[0x13][2] |= key_stat[0x20] ? 0x02 : 0; // sp
559 databuf[0x13][2] |= key_stat[0x0d] ? 0x01 : 0; // ret
566 // if(!databuf[0x14][0]) {
567 while(!key_buf->empty()) {
568 lh = key_buf->read();
570 databuf[0x16][0] = lh & 0xff;
571 databuf[0x16][1] = lh >> 8;
579 if(!databuf[0x14][0]) {
580 // interrupt disabled
581 while(!key_buf->empty()) {
582 lh = key_buf->read();
583 databuf[0x16][0] = lh & 0xff;
584 databuf[0x16][1] = lh >> 8;
588 if(!key_buf->empty()) {
589 lh = key_buf->read();
590 databuf[0x16][0] = lh & 0xff;
591 databuf[0x16][1] = lh >> 8;
594 #ifdef _X1TURBO_FEATURE
595 databuf[0x16][0] &= ~0x1f;
596 databuf[0x16][0] |= get_key_low() & 0x1f;
599 this->out_debug_log(_T("X1 PSUB: keycode %2x %2x\n"), databuf[0x16][0], databuf[0x16][1]);
605 databuf[0x18][0] = databuf[0x17][0];
613 if(databuf[0x1a][0] != databuf[0x19][0]) {
614 uint8_t new_status = databuf[0x19][0];
615 switch(databuf[0x19][0]) {
620 d_drec->set_remote(false);
624 d_drec->set_ff_rew(0);
625 d_drec->set_remote(true);
627 new_status = CMT_STOP;
629 new_status = CMT_EJECT;
634 d_drec->set_ff_rew(1);
635 d_drec->set_remote(true);
637 new_status = CMT_STOP;
639 new_status = CMT_EJECT;
644 d_drec->set_ff_rew(-1);
645 d_drec->set_remote(true);
647 new_status = CMT_STOP;
649 new_status = CMT_EJECT;
655 d_drec->do_apss((databuf[0x19][0] == CMT_APSS_PLUS) ? 1 : -1);
656 new_status = CMT_STOP;
658 new_status = CMT_STOP;
660 new_status = CMT_EJECT;
665 new_status = CMT_STOP;
667 d_drec->set_remote(true);
669 new_status = CMT_EJECT;
674 this->out_debug_log(_T("X1 PSUB: unknown CMT control %2x\n"), databuf[0x19][0]);
678 databuf[0x1a][0] = new_status;
686 // CMT sensor (bit2=WP, bit1=SET, bit0=END)
687 databuf[0x1b][0] = (play ? 2 : rec ? 6 : 0) | (play && eot ? 1 : 0);
692 cur_time.year = FROM_BCD(databuf[0x1c][0]);
693 if((databuf[0x1c][1] & 0xf0) != 0) {
694 cur_time.month = databuf[0x1c][1] >> 4;
696 // cur_time.day_of_week = databuf[0x1c][1] & 7;
697 if(databuf[0x1c][2] != 0) {
698 cur_time.day = FROM_BCD(databuf[0x1c][2]);
700 cur_time.update_year();
701 cur_time.update_day_of_week();
705 databuf[0x1d][0] = TO_BCD(cur_time.year);
706 databuf[0x1d][1] = (cur_time.month << 4) | cur_time.day_of_week;
707 databuf[0x1d][2] = TO_BCD(cur_time.day);
712 cur_time.hour = FROM_BCD(databuf[0x1e][0]);
713 cur_time.minute = FROM_BCD(databuf[0x1e][1] & 0x7f);
714 cur_time.second = FROM_BCD(databuf[0x1e][2] & 0x7f);
716 cancel_event(this, time_register_id);
717 register_event(this, EVENT_1SEC, 1000000, true, &time_register_id);
721 databuf[0x1f][0] = TO_BCD(cur_time.hour);
722 databuf[0x1f][1] = TO_BCD(cur_time.minute);
723 databuf[0x1f][2] = TO_BCD(cur_time.second);
728 this->out_debug_log(_T("X1 PSUB: unknown cmd %2x\n"), mode);
733 void PSUB::set_ibf(bool val)
736 d_pio->write_signal(SIG_I8255_PORT_B, val ? 0xff : 0, 0x40);
741 void PSUB::set_obf(bool val)
744 d_pio->write_signal(SIG_I8255_PORT_B, val ? 0xff : 0, 0x20);
749 uint8_t PSUB::get_key_low()
759 if(key_kana_locked) {
762 if(key_caps_locked) {
766 l &= ~0x10; // graph (alt)
771 uint16_t PSUB::get_key(int code, bool repeat)
773 uint8_t l = get_key_low();
777 l &= ~0x20; // repeat
779 if(0x60 <= code && code <= 0x74) {
780 l &= ~0x80; // function or numpad
782 if(key_kana_locked) {
784 #ifdef _X1TURBO_FEATURE
785 if(config.device_type != 0) {
786 h = keycode_ksb[code]; // kana+shift (mode b)
789 h = keycode_ks[code]; // kana+shift
791 #ifdef _X1TURBO_FEATURE
792 if(config.device_type != 0) {
793 h = keycode_kb[code]; // kana (mode b)
796 h = keycode_k[code]; // kana
800 h = keycode_c[code]; // ctrl
801 } else if(!(l & 0x10)) {
802 h = keycode_g[code]; // graph
805 h = keycode_s[code]; // shift
807 h = keycode[code]; // (none shifted)
809 if(key_caps_locked) {
810 if(0x41 <= code && code <= 0x5a) {
811 h ^= 0x20; // alphabet
816 #ifndef _X1TURBO_FEATURE
824 #define STATE_VERSION 1
826 void PSUB::save_state(FILEIO* state_fio)
828 state_fio->FputUint32(STATE_VERSION);
829 state_fio->FputInt32(this_device_id);
831 cur_time.save_state((void *)state_fio);
832 state_fio->FputInt32(time_register_id);
833 state_fio->Fwrite(databuf, sizeof(databuf), 1);
834 state_fio->FputInt32((int)(datap - &databuf[0][0]));
835 state_fio->FputUint8(mode);
836 state_fio->FputUint8(inbuf);
837 state_fio->FputUint8(outbuf);
838 state_fio->FputBool(ibf);
839 state_fio->FputBool(obf);
840 state_fio->FputInt32(cmdlen);
841 state_fio->FputInt32(datalen);
842 key_buf->save_state((void *)state_fio);
843 state_fio->FputInt32(key_prev);
844 state_fio->FputInt32(key_break);
845 state_fio->FputBool(key_shift);
846 state_fio->FputBool(key_ctrl);
847 state_fio->FputBool(key_graph);
848 state_fio->FputBool(key_caps_locked);
849 state_fio->FputBool(key_kana_locked);
850 state_fio->FputInt32(key_register_id);
851 state_fio->FputBool(play);
852 state_fio->FputBool(rec);
853 state_fio->FputBool(eot);
854 state_fio->FputBool(iei);
855 state_fio->FputBool(intr);
856 state_fio->FputUint32(intr_bit);
859 bool PSUB::load_state(FILEIO* state_fio)
861 if(state_fio->FgetUint32() != STATE_VERSION) {
864 if(state_fio->FgetInt32() != this_device_id) {
867 if(!cur_time.load_state((void *)state_fio)) {
870 time_register_id = state_fio->FgetInt32();
871 state_fio->Fread(databuf, sizeof(databuf), 1);
872 datap = &databuf[0][0] + state_fio->FgetInt32();
873 mode = state_fio->FgetUint8();
874 inbuf = state_fio->FgetUint8();
875 outbuf = state_fio->FgetUint8();
876 ibf = state_fio->FgetBool();
877 obf = state_fio->FgetBool();
878 cmdlen = state_fio->FgetInt32();
879 datalen = state_fio->FgetInt32();
880 if(!key_buf->load_state((void *)state_fio)) {
883 key_prev = state_fio->FgetInt32();
884 key_break = state_fio->FgetInt32();
885 key_shift = state_fio->FgetBool();
886 key_ctrl = state_fio->FgetBool();
887 key_graph = state_fio->FgetBool();
888 key_caps_locked = state_fio->FgetBool();
889 key_kana_locked = state_fio->FgetBool();
890 key_register_id = state_fio->FgetInt32();
891 play = state_fio->FgetBool();
892 rec = state_fio->FgetBool();
893 eot = state_fio->FgetBool();
894 iei = state_fio->FgetBool();
895 intr = state_fio->FgetBool();
896 intr_bit = state_fio->FgetUint32();