OSDN Git Service

[VM][General][WIP] Start to merge upstream 2018-10-14.Open branch upstream_20181014 .
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc2001 / io.cpp
1 /*
2         NEC PC-2001 Emulator 'ePC-2001'
3
4         Origin : PockEmul
5         Author : Takeda.Toshiya
6         Date   : 2016.03.18-
7
8         [ i/o ]
9 */
10
11 #include "./io.h"
12 #include "../datarec.h"
13 #include "../upd16434.h"
14 #include "../upd1990a.h"
15 #include "../upd7810.h"
16 #include "../mame/emu/cpu/upd7810/upd7810.h"
17
18 #define EVENT_TIMER     0
19
20 namespace PC2001 {
21
22 void IO::initialize()
23 {
24         register_event(this, EVENT_TIMER, 20000, true, NULL);
25         key_stat = emu->get_key_buffer();
26 }
27
28 void IO::reset()
29 {
30         port_a = port_b = port_s = 0xff;
31         drec_in = rtc_in = false;
32         key_strobe = 0xffff;
33 }
34
35 void IO::write_io8(uint32_t addr, uint32_t data)
36 {
37         switch(addr) {
38         case UPD7807_PORTA:
39                 #ifdef _IO_DEBUG_LOG
40                         this->out_debug_log("%06x\tOUT8\tPA, %02x\n", get_cpu_pc(0), data);
41                 #endif
42                 d_rtc->write_signal(SIG_UPD1990A_CMD, data & 0x03, 0x07);
43                 d_rtc->write_signal(SIG_UPD1990A_STB, data, 0x08);
44                 d_drec->write_signal(SIG_DATAREC_MIC, data, 0x10);
45                 port_a = data;
46                 break;
47                 
48         case UPD7807_PORTB:
49                 #ifdef _IO_DEBUG_LOG
50                         this->out_debug_log("%06x\tOUT8\tPB, %02x\n", get_cpu_pc(0), data);
51                 #endif
52                 if(!(port_b & 0x04) && (data & 0x04)) {
53                         d_rtc->write_signal(SIG_UPD1990A_DIN, port_s, 0x80);
54                         port_s <<= 1;
55                         port_s |= rtc_in ? 1 : 0;
56                 }
57                 d_rtc->write_signal(SIG_UPD1990A_CLK, data, 0x04);
58 //              d_drec->write_signal(SIG_DATAREC_REMOTE, data, 0x80);
59                 port_b = data;
60                 break;
61                 
62         case UPD7807_PORTC:
63                 #ifdef _IO_DEBUG_LOG
64                         this->out_debug_log("%06x\tOUT8\tPC, %02x\n", get_cpu_pc(0), data);
65                 #endif
66                 break;
67                 
68         case UPD7807_PORTS:
69                 #ifdef _IO_DEBUG_LOG
70                         this->out_debug_log("%06x\tOUT8\tPS, %02x\n", get_cpu_pc(0), data);
71                 #endif
72                 if(port_a & 0x40) {
73                         // output to printer
74                 } else if(port_a & 0x04) {
75                         // lcd command
76                         d_lcd[port_a & 0x03]->instruction(data);
77                 } else {
78                         // lcd data
79                         d_lcd[port_a & 0x03]->data(data);
80                 }
81                 port_s = data;
82                 break;
83         }
84 }
85
86 uint32_t IO::read_io8(uint32_t addr)
87 {
88         uint32_t value = 0xff;
89         
90         switch(addr) {
91         case UPD7807_PORTB:
92                 value = (drec_in ? 0x80 : 0) | ((port_a & 0x40) ? 0 : 0x02);
93                 #ifdef _IO_DEBUG_LOG
94                         this->out_debug_log("%06x\tIN8\tPB = %02x\n", get_cpu_pc(0), value);
95                 #endif
96                 break;
97                 
98         case UPD7807_PORTC:
99                 value = get_key();
100                 #ifdef _IO_DEBUG_LOG
101                         this->out_debug_log("%06x\tIN8\tPC = %02x\n", get_cpu_pc(0), value);
102                 #endif
103                 break;
104                 
105         case UPD7807_PORTS:
106                 value = port_s;
107                 #ifdef _IO_DEBUG_LOG
108                         this->out_debug_log("%06x\tIN8\tPS = %02x\n", get_cpu_pc(0), value);
109                 #endif
110                 break;
111         }
112         return value;
113 }
114
115 void IO::write_io16(uint32_t addr, uint32_t data)
116 {
117         switch(addr) {
118         case UPD7807_PORTE:
119                 #ifdef _IO_DEBUG_LOG
120                         this->out_debug_log("%06x\tOUT16\tPE, %04x\n", get_cpu_pc(0), data);
121                 #endif
122                 key_strobe = data;
123                 break;
124         }
125 }
126
127 void IO::write_signal(int id, uint32_t data, uint32_t mask)
128 {
129         switch(id) {
130         case SIG_IO_DREC_IN:
131                 drec_in = ((data & mask) != 0);
132                 break;
133                 
134         case SIG_IO_RTC_IN:
135                 rtc_in = ((data & mask) != 0);
136                 break;
137         }
138 }
139
140 void IO::event_callback(int event_id, int err)
141 {
142         if(event_id == EVENT_TIMER) {
143                 d_cpu->write_signal(SIG_UPD7810_INTF1, 1, 1);
144         }
145 }
146
147 uint8_t IO::get_key()
148 {
149         uint8_t data = 0x3f;
150         
151         if(!(key_strobe & 0x0001)) {
152                 if(key_hit(0x11)) data &= ~0x02;        // CTRL
153                 if(key_hit(0x10)) data &= ~0x04;        // SHIFT
154         }
155         if(!(key_strobe & 0x0002)) {
156                 if(key_hit(0x51)) data &= ~0x01;        // Q
157                 if(key_hit(0x41)) data &= ~0x02;        // A
158 //              if(key_hit(0x00)) data &= ~0x04;
159                 if(key_hit(0x60)) data &= ~0x08;        // NUMPAD 0
160                 if(key_hit(0x31)) data &= ~0x10;        // 1
161                 if(key_hit(0x5a)) data &= ~0x20;        // Z
162         }
163         if(!(key_strobe & 0x0004)) {
164                 if(key_hit(0x57)) data &= ~0x01;        // W
165                 if(key_hit(0x53)) data &= ~0x02;        // S
166                 if(key_hit(0x58)) data &= ~0x04;        // X
167                 if(key_hit(0x61)) data &= ~0x08;        // NUMPAD 1
168                 if(key_hit(0x32)) data &= ~0x10;        // 2
169                 if(key_hit(0x70)) data &= ~0x20;        // F1
170         }
171         if(!(key_strobe & 0x0008)) {
172                 if(key_hit(0x6c)) data &= ~0x01;        // NUMPAD , (does not exist in the standard keyboard)
173                 if(key_hit(0x44)) data &= ~0x02;        // D
174                 if(key_hit(0x43)) data &= ~0x04;        // C
175                 if(key_hit(0x62)) data &= ~0x08;        // NUMPAD 2
176                 if(key_hit(0x33)) data &= ~0x10;        // 3
177                 if(key_hit(0x71)) data &= ~0x20;        // F2
178         }
179         if(!(key_strobe & 0x0010)) {
180                 if(key_hit(0x52)) data &= ~0x01;        // R
181                 if(key_hit(0x46)) data &= ~0x02;        // F
182                 if(key_hit(0x56)) data &= ~0x04;        // V
183                 if(key_hit(0x63)) data &= ~0x08;        // NUMPAD 3
184                 if(key_hit(0x34)) data &= ~0x10;        // 4
185                 if(key_hit(0x72)) data &= ~0x20;        // F3
186         }
187         if(!(key_strobe & 0x0020)) {
188                 if(key_hit(0x54)) data &= ~0x01;        // T
189                 if(key_hit(0x47)) data &= ~0x02;        // G
190                 if(key_hit(0x42)) data &= ~0x04;        // B
191                 if(key_hit(0x64)) data &= ~0x08;        // NUMPAD 4
192                 if(key_hit(0x35)) data &= ~0x10;        // 5
193                 if(key_hit(0x73)) data &= ~0x20;        // F4
194         }
195         if(!(key_strobe & 0x0040)) {
196                 if(key_hit(0x59)) data &= ~0x01;        // Y
197                 if(key_hit(0x48)) data &= ~0x02;        // H
198                 if(key_hit(0x4e)) data &= ~0x04;        // N
199                 if(key_hit(0x65)) data &= ~0x08;        // NUMPAD 5
200                 if(key_hit(0x36)) data &= ~0x10;        // 6
201                 if(key_hit(0xbc)) data &= ~0x20;        // ,
202         }
203         if(!(key_strobe & 0x0080)) {
204                 if(key_hit(0x55)) data &= ~0x01;        // U
205                 if(key_hit(0x4a)) data &= ~0x02;        // J
206                 if(key_hit(0x4d)) data &= ~0x04;        // M
207                 if(key_hit(0x66)) data &= ~0x08;        // NUMPAD 6
208                 if(key_hit(0x37)) data &= ~0x10;        // 7
209                 if(key_hit(0xbe)) data &= ~0x20;        // .
210         }
211         if(!(key_strobe & 0x0100)) {
212                 if(key_hit(0x49)) data &= ~0x01;        // I
213                 if(key_hit(0x4b)) data &= ~0x02;        // K
214                 if(key_hit(0x6f)) data &= ~0x04;        // NUMPAD /
215                 if(key_hit(0x67)) data &= ~0x08;        // NUMPAD 7
216                 if(key_hit(0x38)) data &= ~0x10;        // 8
217                 if(key_hit(0xbf)) data &= ~0x20;        // /
218         }
219         if(!(key_strobe & 0x0200)) {
220                 if(key_hit(0x4f)) data &= ~0x01;        // O
221                 if(key_hit(0x4c)) data &= ~0x02;        // L
222                 if(key_hit(0x6a)) data &= ~0x04;        // NUMPAD *
223                 if(key_hit(0x68)) data &= ~0x08;        // NUMPAD 8
224                 if(key_hit(0x39)) data &= ~0x10;        // 9
225                 if(key_hit(0xbb)) data &= ~0x20;        // ;
226         }
227         if(!(key_strobe & 0x0400)) {
228                 if(key_hit(0x50)) data &= ~0x01;        // P
229                 if(key_hit(0xdc)) data &= ~0x02;        // YEN
230                 if(key_hit(0x6d)) data &= ~0x04;        // NUMPAD -
231                 if(key_hit(0x69)) data &= ~0x08;        // NUMPAD 9
232                 if(key_hit(0x30)) data &= ~0x10;        // 0
233                 if(key_hit(0xba)) data &= ~0x20;        // :
234         }
235         if(!(key_strobe & 0x0800)) {
236                 if(key_hit(0xc0)) data &= ~0x01;        // @
237 //              if(key_hit(0x00)) data &= ~0x02;
238                 if(key_hit(0x6b)) data &= ~0x04;        // NUMPAD +
239                 if(key_hit(0x45)) data &= ~0x08;        // E
240                 if(key_hit(0xbd)) data &= ~0x10;        // -
241                 if(key_hit(0xdd)) data &= ~0x20;        // ]
242         }
243         if(!(key_strobe & 0x1000)) {
244                 if(key_hit(0xde)) data &= ~0x01;        // ^
245                 if(key_hit(0x20)) data &= ~0x02;        // SPACE
246                 if(key_hit(0x6e)) data &= ~0x04;        // NUMPAD .
247                 if(key_hit(0x26)) data &= ~0x08;        // UP
248                 if(key_hit(0xdb)) data &= ~0x10;        // [
249                 if(key_hit(0xe2)) data &= ~0x20;        // _
250         }
251         if(!(key_strobe & 0x2000)) {
252                 if(key_hit(0x2e)) data &= ~0x01;        // DEL
253                 if(key_hit(0x2d)) data &= ~0x02;        // INS
254 //              if(key_hit(0x00)) data &= ~0x04;
255                 if(key_hit(0x28)) data &= ~0x08;        // DOWN
256                 if(key_hit(0x25)) data &= ~0x10;        // LEFT
257                 if(key_hit(0x27)) data &= ~0x20;        // RIGHT
258         }
259         if(!(key_strobe & 0x4000)) {
260 //              if(key_hit(0x00)) data &= ~0x01;
261                 if(key_hit(0x0d)) data &= ~0x02;        // RETURN
262 //              if(key_hit(0x00)) data &= ~0x04;
263                 // FIXME: EMU/OSD classes cannot detect SHIFT+KANA correctly, so use ALT key for KANA
264                 if(key_hit(0x12)) data &= ~0x08;        // KANA(CAPS) -> ALT
265                 if(key_hit(0x15)) data &= ~0x08;        // NOTE: AUTOKEY sends KANA key code
266                 if(key_hit(0x24)) data &= ~0x10;        // CLR -> HOME
267                 if(key_hit(0x74)) data &= ~0x20;        // F5
268         }
269         return data;
270 }
271
272 bool IO::key_hit(int code)
273 {
274         bool value = (key_stat[code] != 0);
275         return value;
276 }
277
278 #define STATE_VERSION   2
279
280 bool IO::process_state(FILEIO* state_fio, bool loading)
281 {
282         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
283                 return false;
284         }
285         if(!state_fio->StateCheckInt32(this_device_id)) {
286                 return false;
287         }
288         state_fio->StateValue(port_a);
289         state_fio->StateValue(port_b);
290         state_fio->StateValue(port_s);
291         state_fio->StateValue(drec_in);
292         state_fio->StateValue(rtc_in);
293         state_fio->StateValue(key_strobe);
294         return true;
295 }
296
297 }