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 #include "../../fileio.h"
18 //#define DEBUG_COMMAND
22 #define EVENT_REPEAT 2
24 #define CMT_EJECT 0x00
27 #define CMT_FAST_FWD 0x03
28 #define CMT_FAST_REW 0x04
29 #define CMT_APSS_PLUS 0x05
30 #define CMT_APSS_MINUS 0x06
33 // TODO: XFER = 0xe8 ???
35 static const uint8 keycode[256] = { // normal
36 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
38 0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
39 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
41 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
43 0x71, 0x72, 0x73, 0x74, 0x75, 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, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 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, 0x3a, 0x3b, 0x2c, 0x2d, 0x2e, 0x2f,
48 0x40, 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, 0x5b, 0x5c, 0x5d, 0x5e, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
53 static const uint8 keycode_s[256] = { // shift
54 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
56 0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
57 0x30, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
59 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0x3c, 0x2d, 0x2e, 0x3f,
61 0x76, 0x77, 0x78, 0x79, 0x7a, 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, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 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, 0x2a, 0x2b, 0x3c, 0x3d, 0x3e, 0x3f,
66 0x7e, 0x00, 0x00, 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, 0x7b, 0x7c, 0x7d, 0x60, 0x00,
68 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
71 static const uint8 keycode_g[256] = { // graph
72 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00,
74 0x00, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
75 0xfa, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x7f, 0x84, 0x82, 0xea, 0xe2, 0xeb, 0xec, 0xed, 0xe7, 0xee, 0xef, 0x8e, 0x86, 0x85, 0xf0,
77 0x8d, 0xe0, 0xe3, 0xe9, 0xe4, 0xe6, 0x83, 0xe1, 0x81, 0xe5, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x8f, 0x99, 0x92, 0x98, 0x95, 0x96, 0x94, 0x9a, 0x93, 0x97, 0x9b, 0x9d, 0x87, 0x9c, 0x91, 0x9e,
79 0x00, 0x00, 0x00, 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, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 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, 0xfd, 0x89, 0x87, 0x8c, 0x88, 0xfe,
84 0x8a, 0x00, 0x00, 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, 0xfc, 0xfb, 0xe8, 0x8b, 0x00,
86 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
89 static const uint8 keycode_c[256] = { // ctrl
90 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
91 0x1c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
92 0x00, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
93 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
95 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0x00, 0x2d, 0x2e, 0x2f,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xeb, 0xe2, 0xe1, 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, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 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, 0x3a, 0x3b, 0x00, 0x2d, 0x00, 0x00,
102 0x40, 0x00, 0x00, 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, 0x1b, 0x1c, 0x1d, 0x1e, 0x00,
104 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
107 static const uint8 keycode_k[256] = { // kana
108 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
110 0x20, 0x0e, 0x0f, 0x11, 0x0b, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
111 0xdc, 0xc7, 0xcc, 0xb1, 0xb3, 0xb4, 0xb5, 0xd4, 0xd5, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0xc1, 0xba, 0xbf, 0xbc, 0xb2, 0xca, 0xb7, 0xb8, 0xc6, 0xcf, 0xc9, 0xd8, 0xd3, 0xd0, 0xd7,
113 0xbe, 0xc0, 0xbd, 0xc4, 0xb6, 0xc5, 0xcb, 0xc3, 0xbb, 0xdd, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xc8, 0x2d, 0x2e, 0xd2,
115 0x71, 0x72, 0x73, 0x74, 0x75, 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, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 0x00, 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, 0xb9, 0xda, 0xc8, 0xce, 0xd9, 0xd2,
120 0xde, 0x00, 0x00, 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, 0xdf, 0xb0, 0xd1, 0xcd, 0x00,
122 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
125 static const uint8 keycode_ks[256] = { // kana+shift
126 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x12, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xe8, 0x00, 0x00, 0x00,
128 0x20, 0x0e, 0x0f, 0x11, 0x0c, 0x1d, 0x1e, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00,
129 0xa6, 0xc7, 0xcc, 0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0xc1, 0xba, 0xbf, 0xbc, 0xa8, 0xca, 0xb7, 0xb8, 0xc6, 0xcf, 0xc9, 0xd8, 0xd3, 0xd0, 0xd7,
131 0xbe, 0xc0, 0xbd, 0xc4, 0xb6, 0xc5, 0xcb, 0xc3, 0xbb, 0xdd, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2a, 0x2b, 0xa4, 0x2d, 0x2e, 0xa5,
133 0x76, 0x77, 0x78, 0x79, 0x7a, 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, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 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, 0xb9, 0xda, 0xa4, 0xce, 0xa1, 0xa5,
138 0xde, 0x00, 0x00, 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, 0xa2, 0xb0, 0xa3, 0xcd, 0x00,
140 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
144 void PSUB::initialize()
146 key_buf = new FIFO(8);
147 key_stat = emu->key_buffer();
149 emu->get_host_time(&cur_time);
152 register_event(this, EVENT_1SEC, 1000000, true, &time_register_id);
153 register_event(this, EVENT_DRIVE, 400, true, NULL);
164 memset(databuf, 0, sizeof(databuf));
165 databuf[0x16][0] = 0xff;
166 datap = &databuf[0][0]; // temporary fix
168 cmdlen = datalen = 0;
170 play = rec = eot = false;
179 key_prev = key_break = 0;
180 key_shift = key_ctrl = key_graph = false;
181 key_caps_locked = key_kana_locked = false;
182 key_register_id = -1;
189 d_pio->write_signal(SIG_I8255_PORT_B, 0xff, 1);
192 void PSUB::write_io8(uint32 addr, uint32 data)
198 uint32 PSUB::read_io8(uint32 addr)
206 void PSUB::write_signal(int id, uint32 data, uint32 mask)
208 if(id == SIG_PSUB_TAPE_REMOTE) {
209 if(!(data & mask) && (play || rec)) {
210 databuf[0x1a][0] = CMT_STOP;
212 } else if(id == SIG_PSUB_TAPE_END) {
213 eot = ((data & mask) != 0);
217 void PSUB::set_intr_iei(bool val)
225 uint32 PSUB::intr_ack()
227 return read_io8(0x1900);
230 void PSUB::intr_reti()
232 // NOTE: some software uses RET, not RETI ???
235 void PSUB::update_intr()
238 d_cpu->set_intr_line(true, true, intr_bit);
240 d_cpu->set_intr_line(false, true, intr_bit);
244 void PSUB::event_callback(int event_id, int err)
246 if(event_id == EVENT_1SEC) {
247 if(cur_time.initialized) {
248 cur_time.increment();
250 emu->get_host_time(&cur_time); // resync
251 cur_time.initialized = true;
253 } else if(event_id == EVENT_DRIVE) {
255 static const int cmdlen_tbl[] = {
256 0, 1, 0, 0, 1, 0, 1, 0, 0, 3, 0, 3, 0
261 if(vm->cart_inserted(0)) {
267 // sub cpu received data from main cpu
269 // this is command parameter
272 emu->out_debug_log(_T(" %2x"), inbuf);
276 // this is new command
279 emu->out_debug_log(_T("X1 PSUB: cmd %2x"), inbuf);
281 if(0xd0 <= mode && mode <= 0xd7) {
283 datap = &databuf[mode - 0xd0][0]; // receive buffer
284 } else if(0xe3 <= mode && mode <= 0xef) {
285 cmdlen = cmdlen_tbl[mode - 0xe3];
286 datap = &databuf[mode - 0xd0][0]; // receive buffer
290 // this command has no parameters or all parameters are received,
291 // so cpu processes the command
293 emu->out_debug_log(_T("\n"));
297 // sub cpu can accept new command or parameter
301 // if command is not finished, key irq is not raised
302 if(cmdlen || datalen) {
307 // sub cpu can send data to main cpu
309 // sub cpu sends result data
313 } else if(!key_buf->empty() && databuf[0x14][0] && !intr && iei) {
314 // key buffer is not empty and interrupt is not disabled,
315 // so sub cpu sends vector and raise irq
316 outbuf = databuf[0x14][0];
326 } else if(event_id == EVENT_REPEAT) {
327 key_register_id = -1;
328 key_down(key_prev, true);
332 // shift, ctrl, graph, caps, kana
333 #define IS_LOWBYTE_KEY(c) ((c >= 0x10 && c <= 0x12) || c == 0x14 || c == 0x15)
335 void PSUB::key_down(int code, bool repeat)
349 key_caps_locked = !key_caps_locked;
352 key_kana_locked = !key_kana_locked;
355 uint16 lh = get_key(code, repeat);
358 if(!databuf[0x14][0]) {
364 // setup key repeat event
365 if(key_register_id != -1) {
366 cancel_event(this, key_register_id);
367 key_register_id = -1;
369 if(!(0x70 <= code && code <= 0x87)) {
371 register_event(this, EVENT_REPEAT, 61165, false, &key_register_id); // 61.165 msec
373 register_event(this, EVENT_REPEAT, 557085, false, &key_register_id); // 557.085 msec
377 // break key is pressed
379 d_pio->write_signal(SIG_I8255_PORT_B, 0, 1);
382 #ifdef _X1TURBO_FEATURE
383 } else if(key_prev == 0 && IS_LOWBYTE_KEY(code)) {
384 key_buf->write(0xff);
389 void PSUB::key_up(int code)
403 #ifdef _X1TURBO_FEATURE
404 if(code == key_prev || (key_prev == 0 && IS_LOWBYTE_KEY(code))) {
406 if(code == key_prev) {
408 // last pressed key is released
409 if(!databuf[0x14][0]) {
412 key_buf->write(0xff);
414 if(key_register_id != -1) {
415 cancel_event(this, key_register_id);
416 key_register_id = -1;
419 if(code == key_break) {
420 // break key is released
421 d_pio->write_signal(SIG_I8255_PORT_B, 0xff, 1);
426 void PSUB::play_tape(bool value)
429 databuf[0x1a][0] = CMT_STOP;
431 databuf[0x1a][0] = CMT_EJECT;
435 d_drec->set_remote(false);
438 void PSUB::rec_tape(bool value)
441 databuf[0x1a][0] = CMT_STOP;
443 databuf[0x1a][0] = CMT_EJECT;
447 d_drec->set_remote(false);
450 void PSUB::close_tape()
453 databuf[0x1a][0] = CMT_EJECT;
455 d_drec->set_remote(false);
459 void PSUB::process_cmd()
464 if(0xd0 <= mode && mode < 0xf0) {
465 datap = &databuf[mode - 0xd0][0]; // send buffer
472 // reset receive/send buffer
493 datap = &databuf[mode - 0xd8][0]; // data buffer for timer set
496 #ifdef _X1TURBO_FEATURE
498 // game key read (for turbo)
499 databuf[0x13][0] = databuf[0x13][1] = databuf[0x13][2] = 0;
500 if(config.device_type != 0) {
501 databuf[0x13][0] |= key_stat[0x51] ? 0x80 : 0; // q
502 databuf[0x13][0] |= key_stat[0x57] ? 0x40 : 0; // w
503 databuf[0x13][0] |= key_stat[0x45] ? 0x20 : 0; // e
504 databuf[0x13][0] |= key_stat[0x41] ? 0x10 : 0; // a
505 databuf[0x13][0] |= key_stat[0x44] ? 0x08 : 0; // d
506 databuf[0x13][0] |= key_stat[0x5a] ? 0x04 : 0; // z
507 databuf[0x13][0] |= key_stat[0x58] ? 0x02 : 0; // x
508 databuf[0x13][0] |= key_stat[0x43] ? 0x01 : 0; // c
509 databuf[0x13][1] |= key_stat[0x67] ? 0x80 : 0; // 7
510 databuf[0x13][1] |= key_stat[0x64] ? 0x40 : 0; // 4
511 databuf[0x13][1] |= key_stat[0x61] ? 0x20 : 0; // 1
512 databuf[0x13][1] |= key_stat[0x68] ? 0x10 : 0; // 8
513 databuf[0x13][1] |= key_stat[0x62] ? 0x08 : 0; // 2
514 databuf[0x13][1] |= key_stat[0x69] ? 0x04 : 0; // 9
515 databuf[0x13][1] |= key_stat[0x66] ? 0x02 : 0; // 6
516 databuf[0x13][1] |= key_stat[0x63] ? 0x01 : 0; // 3
517 databuf[0x13][2] |= key_stat[0x1b] ? 0x80 : 0; // esc
518 databuf[0x13][2] |= key_stat[0x61] ? 0x40 : 0; // 1
519 databuf[0x13][2] |= key_stat[0x6d] ? 0x20 : 0; // -
520 databuf[0x13][2] |= key_stat[0x6b] ? 0x10 : 0; // +
521 databuf[0x13][2] |= key_stat[0x6a] ? 0x08 : 0; // *
522 databuf[0x13][2] |= key_stat[0x09] ? 0x04 : 0; // tab
523 databuf[0x13][2] |= key_stat[0x20] ? 0x02 : 0; // sp
524 databuf[0x13][2] |= key_stat[0x0d] ? 0x01 : 0; // ret
531 // if(!databuf[0x14][0]) {
532 while(!key_buf->empty()) {
533 lh = key_buf->read();
535 databuf[0x16][0] = lh & 0xff;
536 databuf[0x16][1] = lh >> 8;
544 if(!databuf[0x14][0]) {
545 // interrupt disabled
546 while(!key_buf->empty()) {
547 lh = key_buf->read();
548 databuf[0x16][0] = lh & 0xff;
549 databuf[0x16][1] = lh >> 8;
553 if(!key_buf->empty()) {
554 lh = key_buf->read();
555 databuf[0x16][0] = lh & 0xff;
556 databuf[0x16][1] = lh >> 8;
559 #ifdef _X1TURBO_FEATURE
560 databuf[0x16][0] &= ~0x1f;
561 databuf[0x16][0] |= get_key_low() & 0x1f;
564 emu->out_debug_log(_T("X1 PSUB: keycode %2x %2x\n"), databuf[0x16][0], databuf[0x16][1]);
570 databuf[0x18][0] = databuf[0x17][0];
578 if(databuf[0x1a][0] != databuf[0x19][0]) {
579 uint8 new_status = databuf[0x19][0];
580 switch(databuf[0x19][0]) {
585 d_drec->set_remote(false);
589 d_drec->set_ff_rew(0);
590 d_drec->set_remote(true);
592 new_status = CMT_STOP;
594 new_status = CMT_EJECT;
599 d_drec->set_ff_rew(1);
600 d_drec->set_remote(true);
602 new_status = CMT_STOP;
604 new_status = CMT_EJECT;
609 d_drec->set_ff_rew(-1);
610 d_drec->set_remote(true);
612 new_status = CMT_STOP;
614 new_status = CMT_EJECT;
620 d_drec->do_apss((databuf[0x19][0] == CMT_APSS_PLUS) ? 1 : -1);
621 new_status = CMT_STOP;
623 new_status = CMT_STOP;
625 new_status = CMT_EJECT;
630 new_status = CMT_STOP;
632 d_drec->set_remote(true);
634 new_status = CMT_EJECT;
639 emu->out_debug_log(_T("X1 PSUB: unknown CMT control %2x\n"), databuf[0x19][0]);
643 databuf[0x1a][0] = new_status;
651 // CMT sensor (bit2=WP, bit1=SET, bit0=END)
652 databuf[0x1b][0] = (play ? 2 : rec ? 6 : 0) | (play && eot ? 1 : 0);
657 cur_time.year = FROM_BCD(databuf[0x1c][0]);
658 if((databuf[0x1c][1] & 0xf0) != 0) {
659 cur_time.month = databuf[0x1c][1] >> 4;
661 // cur_time.day_of_week = databuf[0x1c][1] & 7;
662 if(databuf[0x1c][2] != 0) {
663 cur_time.day = FROM_BCD(databuf[0x1c][2]);
665 cur_time.update_year();
666 cur_time.update_day_of_week();
670 databuf[0x1d][0] = TO_BCD(cur_time.year);
671 databuf[0x1d][1] = (cur_time.month << 4) | cur_time.day_of_week;
672 databuf[0x1d][2] = TO_BCD(cur_time.day);
677 cur_time.hour = FROM_BCD(databuf[0x1e][0]);
678 cur_time.minute = FROM_BCD(databuf[0x1e][1] & 0x7f);
679 cur_time.second = FROM_BCD(databuf[0x1e][2] & 0x7f);
681 cancel_event(this, time_register_id);
682 register_event(this, EVENT_1SEC, 1000000, true, &time_register_id);
686 databuf[0x1f][0] = TO_BCD(cur_time.hour);
687 databuf[0x1f][1] = TO_BCD(cur_time.minute);
688 databuf[0x1f][2] = TO_BCD(cur_time.second);
693 emu->out_debug_log(_T("X1 PSUB: unknown cmd %2x\n"), mode);
698 void PSUB::set_ibf(bool val)
701 d_pio->write_signal(SIG_I8255_PORT_B, val ? 0xff : 0, 0x40);
706 void PSUB::set_obf(bool val)
709 d_pio->write_signal(SIG_I8255_PORT_B, val ? 0xff : 0, 0x20);
714 uint8 PSUB::get_key_low()
724 if(key_kana_locked) {
727 if(key_caps_locked) {
731 l &= ~0x10; // graph (alt)
736 uint16 PSUB::get_key(int code, bool repeat)
738 uint8 l = get_key_low();
742 l &= ~0x20; // repeat
744 if(0x60 <= code && code <= 0x74) {
745 l &= ~0x80; // function or numpad
747 if(key_kana_locked) {
749 h = keycode_ks[code]; // kana+shift
751 h = keycode_k[code]; // kana
755 h = keycode_c[code]; // ctrl
756 } else if(!(l & 0x10)) {
757 h = keycode_g[code]; // graph
760 h = keycode_s[code]; // shift
762 h = keycode[code]; // (none shifted)
764 if(key_caps_locked) {
765 if(0x41 <= code && code <= 0x5a) {
766 h ^= 0x20; // alphabet
771 #ifndef _X1TURBO_FEATURE
779 #define STATE_VERSION 1
781 void PSUB::save_state(FILEIO* state_fio)
783 state_fio->FputUint32(STATE_VERSION);
784 state_fio->FputInt32(this_device_id);
786 cur_time.save_state((void *)state_fio);
787 state_fio->FputInt32(time_register_id);
788 state_fio->Fwrite(databuf, sizeof(databuf), 1);
789 state_fio->FputInt32((int)(datap - &databuf[0][0]));
790 state_fio->FputUint8(mode);
791 state_fio->FputUint8(inbuf);
792 state_fio->FputUint8(outbuf);
793 state_fio->FputBool(ibf);
794 state_fio->FputBool(obf);
795 state_fio->FputInt32(cmdlen);
796 state_fio->FputInt32(datalen);
797 key_buf->save_state((void *)state_fio);
798 state_fio->FputInt32(key_prev);
799 state_fio->FputInt32(key_break);
800 state_fio->FputBool(key_shift);
801 state_fio->FputBool(key_ctrl);
802 state_fio->FputBool(key_graph);
803 state_fio->FputBool(key_caps_locked);
804 state_fio->FputBool(key_kana_locked);
805 state_fio->FputInt32(key_register_id);
806 state_fio->FputBool(play);
807 state_fio->FputBool(rec);
808 state_fio->FputBool(eot);
809 state_fio->FputBool(iei);
810 state_fio->FputBool(intr);
811 state_fio->FputUint32(intr_bit);
814 bool PSUB::load_state(FILEIO* state_fio)
816 if(state_fio->FgetUint32() != STATE_VERSION) {
819 if(state_fio->FgetInt32() != this_device_id) {
822 if(!cur_time.load_state((void *)state_fio)) {
825 time_register_id = state_fio->FgetInt32();
826 state_fio->Fread(databuf, sizeof(databuf), 1);
827 datap = &databuf[0][0] + state_fio->FgetInt32();
828 mode = state_fio->FgetUint8();
829 inbuf = state_fio->FgetUint8();
830 outbuf = state_fio->FgetUint8();
831 ibf = state_fio->FgetBool();
832 obf = state_fio->FgetBool();
833 cmdlen = state_fio->FgetInt32();
834 datalen = state_fio->FgetInt32();
835 if(!key_buf->load_state((void *)state_fio)) {
838 key_prev = state_fio->FgetInt32();
839 key_break = state_fio->FgetInt32();
840 key_shift = state_fio->FgetBool();
841 key_ctrl = state_fio->FgetBool();
842 key_graph = state_fio->FgetBool();
843 key_caps_locked = state_fio->FgetBool();
844 key_kana_locked = state_fio->FgetBool();
845 key_register_id = state_fio->FgetInt32();
846 play = state_fio->FgetBool();
847 rec = state_fio->FgetBool();
848 eot = state_fio->FgetBool();
849 iei = state_fio->FgetBool();
850 intr = state_fio->FgetBool();
851 intr_bit = state_fio->FgetUint32();