OSDN Git Service

0cd90884352c03ae9a2f61a7a78a30e9235e7c7c
[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 void PC2001_IO::initialize()
21 {
22         register_event(this, EVENT_TIMER, 20000, true, NULL);
23         key_stat = emu->get_key_buffer();
24 }
25
26 void PC2001_IO::reset()
27 {
28         port_a = port_b = port_s = 0xff;
29         drec_in = rtc_in = false;
30         key_strobe = 0xffff;
31 }
32
33 void PC2001_IO::write_io8(uint32_t addr, uint32_t data)
34 {
35         switch(addr) {
36         case UPD7807_PORTA:
37                 #ifdef _IO_DEBUG_LOG
38                         this->out_debug_log("%06x\tOUT8\tPA, %02x\n", get_cpu_pc(0), data);
39                 #endif
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);
43                 port_a = data;
44                 break;
45                 
46         case UPD7807_PORTB:
47                 #ifdef _IO_DEBUG_LOG
48                         this->out_debug_log("%06x\tOUT8\tPB, %02x\n", get_cpu_pc(0), data);
49                 #endif
50                 if(!(port_b & 0x04) && (data & 0x04)) {
51                         d_rtc->write_signal(SIG_UPD1990A_DIN, port_s, 0x80);
52                         port_s <<= 1;
53                         port_s |= rtc_in ? 1 : 0;
54                 }
55                 d_rtc->write_signal(SIG_UPD1990A_CLK, data, 0x04);
56 //              d_drec->write_signal(SIG_DATAREC_REMOTE, data, 0x80);
57                 port_b = data;
58                 break;
59                 
60         case UPD7807_PORTC:
61                 #ifdef _IO_DEBUG_LOG
62                         this->out_debug_log("%06x\tOUT8\tPC, %02x\n", get_cpu_pc(0), data);
63                 #endif
64                 break;
65                 
66         case UPD7807_PORTS:
67                 #ifdef _IO_DEBUG_LOG
68                         this->out_debug_log("%06x\tOUT8\tPS, %02x\n", get_cpu_pc(0), data);
69                 #endif
70                 if(port_a & 0x40) {
71                         // output to printer
72                 } else if(port_a & 0x04) {
73                         // lcd command
74                         d_lcd[port_a & 0x03]->instruction(data);
75                 } else {
76                         // lcd data
77                         d_lcd[port_a & 0x03]->data(data);
78                 }
79                 port_s = data;
80                 break;
81         }
82 }
83
84 uint32_t PC2001_IO::read_io8(uint32_t addr)
85 {
86         uint32_t value = 0xff;
87         
88         switch(addr) {
89         case UPD7807_PORTB:
90                 value = (drec_in ? 0x80 : 0) | ((port_a & 0x40) ? 0 : 0x02);
91                 #ifdef _IO_DEBUG_LOG
92                         this->out_debug_log("%06x\tIN8\tPB = %02x\n", get_cpu_pc(0), value);
93                 #endif
94                 break;
95                 
96         case UPD7807_PORTC:
97                 value = get_key();
98                 #ifdef _IO_DEBUG_LOG
99                         this->out_debug_log("%06x\tIN8\tPC = %02x\n", get_cpu_pc(0), value);
100                 #endif
101                 break;
102                 
103         case UPD7807_PORTS:
104                 value = port_s;
105                 #ifdef _IO_DEBUG_LOG
106                         this->out_debug_log("%06x\tIN8\tPS = %02x\n", get_cpu_pc(0), value);
107                 #endif
108                 break;
109         }
110         return value;
111 }
112
113 void PC2001_IO::write_io16(uint32_t addr, uint32_t data)
114 {
115         switch(addr) {
116         case UPD7807_PORTE:
117                 #ifdef _IO_DEBUG_LOG
118                         this->out_debug_log("%06x\tOUT16\tPE, %04x\n", get_cpu_pc(0), data);
119                 #endif
120                 key_strobe = data;
121                 break;
122         }
123 }
124
125 void PC2001_IO::write_signal(int id, uint32_t data, uint32_t mask)
126 {
127         switch(id) {
128         case SIG_IO_DREC_IN:
129                 drec_in = ((data & mask) != 0);
130                 break;
131                 
132         case SIG_IO_RTC_IN:
133                 rtc_in = ((data & mask) != 0);
134                 break;
135         }
136 }
137
138 void PC2001_IO::event_callback(int event_id, int err)
139 {
140         if(event_id == EVENT_TIMER) {
141                 d_cpu->write_signal(SIG_UPD7810_INTF1, 1, 1);
142         }
143 }
144
145 uint8_t PC2001_IO::get_key()
146 {
147         uint8_t data = 0x3f;
148         
149         if(!(key_strobe & 0x0001)) {
150                 if(key_hit(0x11)) data &= ~0x02;        // CTRL
151                 if(key_hit(0x10)) data &= ~0x04;        // SHIFT
152         }
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
160         }
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
168         }
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
176         }
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
184         }
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
192         }
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;        // ,
200         }
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;        // .
208         }
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;        // /
216         }
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;        // ;
224         }
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;        // :
232         }
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;        // ]
240         }
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;        // _
248         }
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
256         }
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
266         }
267         return data;
268 }
269
270 bool PC2001_IO::key_hit(int code)
271 {
272         bool value = (key_stat[code] != 0);
273         return value;
274 }
275
276 #define STATE_VERSION   2
277
278 bool PC2001_IO::process_state(FILEIO* state_fio, bool loading)
279 {
280         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
281                 return false;
282         }
283         if(!state_fio->StateCheckInt32(this_device_id)) {
284                 return false;
285         }
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);
292         return true;
293 }