2 NEC PC-100 Emulator 'ePC-100'
4 Author : Takeda.Toshiya
13 #include "../pcm1bit.h"
14 #include "../upd765a.h"
15 #include "../../fifo.h"
17 static const int key_table[256] = {
18 -1, -1, -1, -1, -1, -1, -1, -1,0x18,0x12, -1, -1, -1,0x38, -1, -1,
19 -1,0x04,0x05,0x09, -1, -1, -1, -1, -1,0x10, -1,0x11, -1, -1, -1, -1,
20 0x4A, -1, -1,0x5B,0x5A,0x15,0x13,0x16,0x14, -1, -1, -1, -1,0x17, -1, -1,
21 0x27,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x26, -1, -1, -1, -1, -1, -1,
22 -1,0x31,0x45,0x43,0x33,0x23,0x34,0x35,0x36,0x30,0x3F,0x40,0x3B,0x47,0x46,0x2B,
23 0x29,0x21,0x2C,0x32,0x2D,0x2F,0x44,0x22,0x3A,0x2E,0x39, -1, -1, -1, -1, -1,
24 0x4B,0x4F,0x50,0x51,0x52,0x53,0x54,0x56,0x57,0x58,0x59,0x55, -1,0x5C,0x4D,0x5D,
25 0x0B,0x0C,0x0D,0x0E,0x0F, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
26 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
27 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
28 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
29 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,0x3D,0x3C,0x48,0x28,0x41,0x42,
30 0x2A, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,0x37,0x25,0x3E,0x24, -1,
32 -1, -1,0x49, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
33 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
42 void IOCTRL::initialize()
45 key_stat = emu->get_key_buffer();
46 mouse_stat = emu->get_mouse_buffer();
47 key_buf = new FIFO(64);
54 register_event_by_clock(this, EVENT_600HZ, CPU_CLOCKS / 600, true, NULL);
55 register_event_by_clock(this, EVENT_100HZ, CPU_CLOCKS / 100, true, NULL);
56 register_event_by_clock(this, EVENT_50HZ, CPU_CLOCKS / 50, true, NULL);
57 register_event_by_clock(this, EVENT_10HZ, CPU_CLOCKS / 10, true, NULL);
60 void IOCTRL::release()
68 key_val = key_mouse = 0;
73 key_buf->write(0x1f0);
74 key_buf->write(0x100);
79 void IOCTRL::write_io8(uint32 addr, uint32 data)
81 switch(addr & 0x3f0) {
84 d_beep->write_signal(SIG_BEEP_ON, ~data, 0x40); // tone (2400hz)
85 d_pcm->write_signal(SIG_PCM1BIT_ON, data, 0x40); // direct
86 d_pcm->write_signal(SIG_PCM1BIT_SIGNAL, data, 0x80); // signal
90 d_fdc->write_signal(SIG_UPD765A_TC, data, 0x40);
95 uint32 IOCTRL::read_io8(uint32 addr)
97 switch(addr & 0x3ff) {
103 if(config.monitor_type) {
104 return key_mouse | 0x0d; // virt monitor
106 return key_mouse | 0x2d; // horiz monitor
112 void IOCTRL::event_callback(int event_id, int err)
114 if(event_id == EVENT_KEY) {
115 if(!key_buf->empty()) {
116 key_val = key_buf->read();
117 key_mouse = (key_val & 0x100) ? 0x10 : 0;
120 d_pic->write_signal(SIG_I8259_IR3, 1, 1);
123 } else if(event_id == EVENT_600HZ) {
125 d_pic->write_signal(SIG_I8259_IR2, 1, 1);
127 } else if(event_id == EVENT_100HZ) {
129 d_pic->write_signal(SIG_I8259_IR2, 1, 1);
131 } else if(event_id == EVENT_50HZ) {
133 d_pic->write_signal(SIG_I8259_IR2, 1, 1);
136 if(key_buf->empty()) {
138 if(!(mouse_stat[2] & 1)) val |= 1;
139 if(!(mouse_stat[2] & 2)) val |= 2;
140 if(caps) val |= 0x10;
141 if(kana) val |= 0x20;
142 if(key_stat[0xa0]) val |= 0x40; // lshift
143 if(key_stat[0xa1]) val |= 0x80; // rshift
144 if(mouse_stat[0] || mouse_stat[1]) {
145 key_buf->write(val | 4);
146 key_buf->write(mouse_stat[0] & 0xff);
147 key_buf->write(mouse_stat[1] & 0xff);
150 } else if(key_prev != val) {
156 } else if(event_id == EVENT_10HZ) {
158 d_pic->write_signal(SIG_I8259_IR2, 1, 1);
163 void IOCTRL::write_signal(int id, uint32 data, uint32 mask)
165 bool next = ((data & mask) != 0);
166 if(!key_res && next) {
170 key_buf->write(0x1f0); // dummy
171 key_buf->write(0x1f0); // init code
172 key_buf->write(0x100); // error code
179 void IOCTRL::key_down(int code)
183 } else if(code == 0x15) {
185 } else if((code = key_table[code & 0xff]) != -1) {
187 key_buf->write(code | 0x100);
192 void IOCTRL::key_up(int code)
194 if((code = key_table[code & 0xff]) != -1) {
196 key_buf->write(code | 0x100);
201 void IOCTRL::update_key()
203 if(key_done && !key_buf->empty()) {
204 if(register_id == -1) {
205 register_event(this, EVENT_KEY, 1000, false, ®ister_id);
210 #define STATE_VERSION 1
212 void IOCTRL::save_state(FILEIO* state_fio)
214 state_fio->FputUint32(STATE_VERSION);
215 state_fio->FputInt32(this_device_id);
217 state_fio->FputBool(caps);
218 state_fio->FputBool(kana);
219 key_buf->save_state((void *)state_fio);
220 state_fio->FputUint32(key_val);
221 state_fio->FputUint32(key_mouse);
222 state_fio->FputInt32(key_prev);
223 state_fio->FputBool(key_res);
224 state_fio->FputBool(key_done);
225 state_fio->FputInt32(register_id);
226 state_fio->FputUint8(ts);
229 bool IOCTRL::load_state(FILEIO* state_fio)
231 if(state_fio->FgetUint32() != STATE_VERSION) {
234 if(state_fio->FgetInt32() != this_device_id) {
237 caps = state_fio->FgetBool();
238 kana = state_fio->FgetBool();
239 if(!key_buf->load_state((void *)state_fio)) {
242 key_val = state_fio->FgetUint32();
243 key_mouse = state_fio->FgetUint32();
244 key_prev = state_fio->FgetInt32();
245 key_res = state_fio->FgetBool();
246 key_done = state_fio->FgetBool();
247 register_id = state_fio->FgetInt32();
248 ts = state_fio->FgetUint8();