2 NEC PC-2001 Emulator 'ePC-2001'
5 Author : Takeda.Toshiya
12 #include "../datarec.h"
13 #include "../upd16434.h"
14 #include "../upd1990a.h"
15 #include "../upd7810.h"
16 #include "../mame/emu/cpu/upd7810/upd7810.h"
20 void PC2001_IO::initialize()
22 register_event(this, EVENT_TIMER, 20000, true, NULL);
23 key_stat = emu->get_key_buffer();
26 void PC2001_IO::reset()
28 port_a = port_b = port_s = 0xff;
29 drec_in = rtc_in = false;
33 void PC2001_IO::write_io8(uint32_t addr, uint32_t data)
38 this->out_debug_log("%06x\tOUT8\tPA, %02x\n", get_cpu_pc(0), data);
40 d_rtc->write_signal(SIG_UPD1990A_CMD, data & 0x03, 0x07);
41 d_rtc->write_signal(SIG_UPD1990A_STB, data, 0x08);
42 d_drec->write_signal(SIG_DATAREC_MIC, data, 0x10);
48 this->out_debug_log("%06x\tOUT8\tPB, %02x\n", get_cpu_pc(0), data);
50 if(!(port_b & 0x04) && (data & 0x04)) {
51 d_rtc->write_signal(SIG_UPD1990A_DIN, port_s, 0x80);
53 port_s |= rtc_in ? 1 : 0;
55 d_rtc->write_signal(SIG_UPD1990A_CLK, data, 0x04);
56 // d_drec->write_signal(SIG_DATAREC_REMOTE, data, 0x80);
62 this->out_debug_log("%06x\tOUT8\tPC, %02x\n", get_cpu_pc(0), data);
68 this->out_debug_log("%06x\tOUT8\tPS, %02x\n", get_cpu_pc(0), data);
72 } else if(port_a & 0x04) {
74 d_lcd[port_a & 0x03]->instruction(data);
77 d_lcd[port_a & 0x03]->data(data);
84 uint32_t PC2001_IO::read_io8(uint32_t addr)
86 uint32_t value = 0xff;
90 value = (drec_in ? 0x80 : 0) | ((port_a & 0x40) ? 0 : 0x02);
92 this->out_debug_log("%06x\tIN8\tPB = %02x\n", get_cpu_pc(0), value);
99 this->out_debug_log("%06x\tIN8\tPC = %02x\n", get_cpu_pc(0), value);
106 this->out_debug_log("%06x\tIN8\tPS = %02x\n", get_cpu_pc(0), value);
113 void PC2001_IO::write_io16(uint32_t addr, uint32_t data)
118 this->out_debug_log("%06x\tOUT16\tPE, %04x\n", get_cpu_pc(0), data);
125 void PC2001_IO::write_signal(int id, uint32_t data, uint32_t mask)
129 drec_in = ((data & mask) != 0);
133 rtc_in = ((data & mask) != 0);
138 void PC2001_IO::event_callback(int event_id, int err)
140 if(event_id == EVENT_TIMER) {
141 d_cpu->write_signal(SIG_UPD7810_INTF1, 1, 1);
145 uint8_t PC2001_IO::get_key()
149 if(!(key_strobe & 0x0001)) {
150 if(key_hit(0x11)) data &= ~0x02; // CTRL
151 if(key_hit(0x10)) data &= ~0x04; // SHIFT
153 if(!(key_strobe & 0x0002)) {
154 if(key_hit(0x51)) data &= ~0x01; // Q
155 if(key_hit(0x41)) data &= ~0x02; // A
156 // if(key_hit(0x00)) data &= ~0x04;
157 if(key_hit(0x60)) data &= ~0x08; // NUMPAD 0
158 if(key_hit(0x31)) data &= ~0x10; // 1
159 if(key_hit(0x5a)) data &= ~0x20; // Z
161 if(!(key_strobe & 0x0004)) {
162 if(key_hit(0x57)) data &= ~0x01; // W
163 if(key_hit(0x53)) data &= ~0x02; // S
164 if(key_hit(0x58)) data &= ~0x04; // X
165 if(key_hit(0x61)) data &= ~0x08; // NUMPAD 1
166 if(key_hit(0x32)) data &= ~0x10; // 2
167 if(key_hit(0x70)) data &= ~0x20; // F1
169 if(!(key_strobe & 0x0008)) {
170 if(key_hit(0x6c)) data &= ~0x01; // NUMPAD , (does not exist in the standard keyboard)
171 if(key_hit(0x44)) data &= ~0x02; // D
172 if(key_hit(0x43)) data &= ~0x04; // C
173 if(key_hit(0x62)) data &= ~0x08; // NUMPAD 2
174 if(key_hit(0x33)) data &= ~0x10; // 3
175 if(key_hit(0x71)) data &= ~0x20; // F2
177 if(!(key_strobe & 0x0010)) {
178 if(key_hit(0x52)) data &= ~0x01; // R
179 if(key_hit(0x46)) data &= ~0x02; // F
180 if(key_hit(0x56)) data &= ~0x04; // V
181 if(key_hit(0x63)) data &= ~0x08; // NUMPAD 3
182 if(key_hit(0x34)) data &= ~0x10; // 4
183 if(key_hit(0x72)) data &= ~0x20; // F3
185 if(!(key_strobe & 0x0020)) {
186 if(key_hit(0x54)) data &= ~0x01; // T
187 if(key_hit(0x47)) data &= ~0x02; // G
188 if(key_hit(0x42)) data &= ~0x04; // B
189 if(key_hit(0x64)) data &= ~0x08; // NUMPAD 4
190 if(key_hit(0x35)) data &= ~0x10; // 5
191 if(key_hit(0x73)) data &= ~0x20; // F4
193 if(!(key_strobe & 0x0040)) {
194 if(key_hit(0x59)) data &= ~0x01; // Y
195 if(key_hit(0x48)) data &= ~0x02; // H
196 if(key_hit(0x4e)) data &= ~0x04; // N
197 if(key_hit(0x65)) data &= ~0x08; // NUMPAD 5
198 if(key_hit(0x36)) data &= ~0x10; // 6
199 if(key_hit(0xbc)) data &= ~0x20; // ,
201 if(!(key_strobe & 0x0080)) {
202 if(key_hit(0x55)) data &= ~0x01; // U
203 if(key_hit(0x4a)) data &= ~0x02; // J
204 if(key_hit(0x4d)) data &= ~0x04; // M
205 if(key_hit(0x66)) data &= ~0x08; // NUMPAD 6
206 if(key_hit(0x37)) data &= ~0x10; // 7
207 if(key_hit(0xbe)) data &= ~0x20; // .
209 if(!(key_strobe & 0x0100)) {
210 if(key_hit(0x49)) data &= ~0x01; // I
211 if(key_hit(0x4b)) data &= ~0x02; // K
212 if(key_hit(0x6f)) data &= ~0x04; // NUMPAD /
213 if(key_hit(0x67)) data &= ~0x08; // NUMPAD 7
214 if(key_hit(0x38)) data &= ~0x10; // 8
215 if(key_hit(0xbf)) data &= ~0x20; // /
217 if(!(key_strobe & 0x0200)) {
218 if(key_hit(0x4f)) data &= ~0x01; // O
219 if(key_hit(0x4c)) data &= ~0x02; // L
220 if(key_hit(0x6a)) data &= ~0x04; // NUMPAD *
221 if(key_hit(0x68)) data &= ~0x08; // NUMPAD 8
222 if(key_hit(0x39)) data &= ~0x10; // 9
223 if(key_hit(0xbb)) data &= ~0x20; // ;
225 if(!(key_strobe & 0x0400)) {
226 if(key_hit(0x50)) data &= ~0x01; // P
227 if(key_hit(0xdc)) data &= ~0x02; // YEN
228 if(key_hit(0x6d)) data &= ~0x04; // NUMPAD -
229 if(key_hit(0x69)) data &= ~0x08; // NUMPAD 9
230 if(key_hit(0x30)) data &= ~0x10; // 0
231 if(key_hit(0xba)) data &= ~0x20; // :
233 if(!(key_strobe & 0x0800)) {
234 if(key_hit(0xc0)) data &= ~0x01; // @
235 // if(key_hit(0x00)) data &= ~0x02;
236 if(key_hit(0x6b)) data &= ~0x04; // NUMPAD +
237 if(key_hit(0x45)) data &= ~0x08; // E
238 if(key_hit(0xbd)) data &= ~0x10; // -
239 if(key_hit(0xdd)) data &= ~0x20; // ]
241 if(!(key_strobe & 0x1000)) {
242 if(key_hit(0xde)) data &= ~0x01; // ^
243 if(key_hit(0x20)) data &= ~0x02; // SPACE
244 if(key_hit(0x6e)) data &= ~0x04; // NUMPAD .
245 if(key_hit(0x26)) data &= ~0x08; // UP
246 if(key_hit(0xdb)) data &= ~0x10; // [
247 if(key_hit(0xe2)) data &= ~0x20; // _
249 if(!(key_strobe & 0x2000)) {
250 if(key_hit(0x2e)) data &= ~0x01; // DEL
251 if(key_hit(0x2d)) data &= ~0x02; // INS
252 // if(key_hit(0x00)) data &= ~0x04;
253 if(key_hit(0x28)) data &= ~0x08; // DOWN
254 if(key_hit(0x25)) data &= ~0x10; // LEFT
255 if(key_hit(0x27)) data &= ~0x20; // RIGHT
257 if(!(key_strobe & 0x4000)) {
258 // if(key_hit(0x00)) data &= ~0x01;
259 if(key_hit(0x0d)) data &= ~0x02; // RETURN
260 // if(key_hit(0x00)) data &= ~0x04;
261 // FIXME: EMU/OSD classes cannot detect SHIFT+KANA correctly, so use ALT key for KANA
262 if(key_hit(0x12)) data &= ~0x08; // KANA(CAPS) -> ALT
263 if(key_hit(0x15)) data &= ~0x08; // NOTE: AUTOKEY sends KANA key code
264 if(key_hit(0x24)) data &= ~0x10; // CLR -> HOME
265 if(key_hit(0x74)) data &= ~0x20; // F5
270 bool PC2001_IO::key_hit(int code)
272 bool value = (key_stat[code] != 0);
276 #define STATE_VERSION 2
278 bool PC2001_IO::process_state(FILEIO* state_fio, bool loading)
280 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
283 if(!state_fio->StateCheckInt32(this_device_id)) {
286 state_fio->StateUint8(port_a);
287 state_fio->StateUint8(port_b);
288 state_fio->StateUint8(port_s);
289 state_fio->StateBool(drec_in);
290 state_fio->StateBool(rtc_in);
291 state_fio->StateUint16(key_strobe);