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);
493 #if defined(USE_SOUND_FILES)
494 d_drec->write_signal(SIG_SOUNDER_ADD + DATAREC_SNDFILE_EJECT, 1, 1);
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);
631 #if defined(USE_SOUND_FILES)
632 d_drec->write_signal(SIG_SOUNDER_ADD + DATAREC_SNDFILE_PLAY, 1, 1);
635 new_status = CMT_STOP;
637 new_status = CMT_EJECT;
642 d_drec->set_ff_rew(1);
643 d_drec->set_remote(true);
644 #if defined(USE_SOUND_FILES)
645 //d_drec->write_signal(SIG_SOUNDER_ADD + DATAREC_SNDFILE_FF, 1, 1);
648 new_status = CMT_STOP;
650 new_status = CMT_EJECT;
655 d_drec->set_ff_rew(-1);
656 d_drec->set_remote(true);
657 #if defined(USE_SOUND_FILES)
658 //d_drec->write_signal(SIG_SOUNDER_ADD + DATAREC_SNDFILE_REW, 1, 1);
661 new_status = CMT_STOP;
663 new_status = CMT_EJECT;
669 #if defined(USE_SOUND_FILES)
670 //d_drec->write_signal(SIG_SOUNDER_ADD + DATAREC_SNDFILE_REW, 1, 1);
672 d_drec->do_apss((databuf[0x19][0] == CMT_APSS_PLUS) ? 1 : -1);
673 new_status = CMT_STOP;
675 new_status = CMT_STOP;
677 new_status = CMT_EJECT;
682 new_status = CMT_STOP;
684 #if defined(USE_SOUND_FILES)
685 d_drec->write_signal(SIG_SOUNDER_ADD + DATAREC_SNDFILE_PLAY, 1, 1);
687 d_drec->set_remote(true);
689 new_status = CMT_EJECT;
694 this->out_debug_log(_T("X1 PSUB: unknown CMT control %2x\n"), databuf[0x19][0]);
698 #if defined(USE_SOUND_FILES)
699 if(new_status == CMT_EJECT) {
700 d_drec->write_signal(SIG_SOUNDER_ADD + DATAREC_SNDFILE_EJECT, 1, 1);
701 } else if(new_status == CMT_STOP) {
702 d_drec->write_signal(SIG_SOUNDER_ADD + DATAREC_SNDFILE_STOP, 1, 1);
706 databuf[0x1a][0] = new_status;
715 // CMT sensor (bit2=WP, bit1=SET, bit0=END)
716 databuf[0x1b][0] = (play ? 2 : rec ? 6 : 0) | (play && eot ? 1 : 0);
721 cur_time.year = FROM_BCD(databuf[0x1c][0]);
722 if((databuf[0x1c][1] & 0xf0) != 0) {
723 cur_time.month = databuf[0x1c][1] >> 4;
725 // cur_time.day_of_week = databuf[0x1c][1] & 7;
726 if(databuf[0x1c][2] != 0) {
727 cur_time.day = FROM_BCD(databuf[0x1c][2]);
729 cur_time.update_year();
730 cur_time.update_day_of_week();
734 databuf[0x1d][0] = TO_BCD(cur_time.year);
735 databuf[0x1d][1] = (cur_time.month << 4) | cur_time.day_of_week;
736 databuf[0x1d][2] = TO_BCD(cur_time.day);
741 cur_time.hour = FROM_BCD(databuf[0x1e][0]);
742 cur_time.minute = FROM_BCD(databuf[0x1e][1] & 0x7f);
743 cur_time.second = FROM_BCD(databuf[0x1e][2] & 0x7f);
745 cancel_event(this, time_register_id);
746 register_event(this, EVENT_1SEC, 1000000, true, &time_register_id);
750 databuf[0x1f][0] = TO_BCD(cur_time.hour);
751 databuf[0x1f][1] = TO_BCD(cur_time.minute);
752 databuf[0x1f][2] = TO_BCD(cur_time.second);
757 this->out_debug_log(_T("X1 PSUB: unknown cmd %2x\n"), mode);
762 void PSUB::set_ibf(bool val)
765 d_pio->write_signal(SIG_I8255_PORT_B, val ? 0xff : 0, 0x40);
770 void PSUB::set_obf(bool val)
773 d_pio->write_signal(SIG_I8255_PORT_B, val ? 0xff : 0, 0x20);
778 uint8_t PSUB::get_key_low()
788 if(key_kana_locked) {
791 if(key_caps_locked) {
795 l &= ~0x10; // graph (alt)
800 uint16_t PSUB::get_key(int code, bool repeat)
802 uint8_t l = get_key_low();
806 l &= ~0x20; // repeat
808 if(0x60 <= code && code <= 0x74) {
809 l &= ~0x80; // function or numpad
811 if(key_kana_locked) {
813 #ifdef _X1TURBO_FEATURE
814 if(config.keyboard_type != 0) {
815 h = keycode_ksb[code]; // kana+shift (mode b)
818 h = keycode_ks[code]; // kana+shift
820 #ifdef _X1TURBO_FEATURE
821 if(config.keyboard_type != 0) {
822 h = keycode_kb[code]; // kana (mode b)
825 h = keycode_k[code]; // kana
829 h = keycode_c[code]; // ctrl
830 } else if(!(l & 0x10)) {
831 h = keycode_g[code]; // graph
834 h = keycode_s[code]; // shift
836 h = keycode[code]; // (none shifted)
838 if(key_caps_locked) {
839 if(0x41 <= code && code <= 0x5a) {
840 h ^= 0x20; // alphabet
845 #ifndef _X1TURBO_FEATURE
853 #define STATE_VERSION 1
855 void PSUB::save_state(FILEIO* state_fio)
857 state_fio->FputUint32(STATE_VERSION);
858 state_fio->FputInt32(this_device_id);
860 cur_time.save_state((void *)state_fio);
861 state_fio->FputInt32(time_register_id);
862 state_fio->Fwrite(databuf, sizeof(databuf), 1);
863 state_fio->FputInt32((int)(datap - &databuf[0][0]));
864 state_fio->FputUint8(mode);
865 state_fio->FputUint8(inbuf);
866 state_fio->FputUint8(outbuf);
867 state_fio->FputBool(ibf);
868 state_fio->FputBool(obf);
869 state_fio->FputInt32(cmdlen);
870 state_fio->FputInt32(datalen);
871 key_buf->save_state((void *)state_fio);
872 state_fio->FputInt32(key_prev);
873 state_fio->FputInt32(key_break);
874 state_fio->FputBool(key_shift);
875 state_fio->FputBool(key_ctrl);
876 state_fio->FputBool(key_graph);
877 state_fio->FputBool(key_caps_locked);
878 state_fio->FputBool(key_kana_locked);
879 state_fio->FputInt32(key_register_id);
880 state_fio->FputBool(play);
881 state_fio->FputBool(rec);
882 state_fio->FputBool(eot);
883 state_fio->FputBool(iei);
884 state_fio->FputBool(intr);
885 state_fio->FputUint32(intr_bit);
888 bool PSUB::load_state(FILEIO* state_fio)
890 if(state_fio->FgetUint32() != STATE_VERSION) {
893 if(state_fio->FgetInt32() != this_device_id) {
896 if(!cur_time.load_state((void *)state_fio)) {
899 time_register_id = state_fio->FgetInt32();
900 state_fio->Fread(databuf, sizeof(databuf), 1);
901 datap = &databuf[0][0] + state_fio->FgetInt32();
902 mode = state_fio->FgetUint8();
903 inbuf = state_fio->FgetUint8();
904 outbuf = state_fio->FgetUint8();
905 ibf = state_fio->FgetBool();
906 obf = state_fio->FgetBool();
907 cmdlen = state_fio->FgetInt32();
908 datalen = state_fio->FgetInt32();
909 if(!key_buf->load_state((void *)state_fio)) {
912 key_prev = state_fio->FgetInt32();
913 key_break = state_fio->FgetInt32();
914 key_shift = state_fio->FgetBool();
915 key_ctrl = state_fio->FgetBool();
916 key_graph = state_fio->FgetBool();
917 key_caps_locked = state_fio->FgetBool();
918 key_kana_locked = state_fio->FgetBool();
919 key_register_id = state_fio->FgetInt32();
920 play = state_fio->FgetBool();
921 rec = state_fio->FgetBool();
922 eot = state_fio->FgetBool();
923 iei = state_fio->FgetBool();
924 intr = state_fio->FgetBool();
925 intr_bit = state_fio->FgetUint32();