OSDN Git Service

[VM][WIP] Use namespace to devices per VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / mz2500 / cmt.cpp
1 /*
2         SHARP MZ-80B Emulator 'EmuZ-80B'
3         SHARP MZ-2200 Emulator 'EmuZ-2200'
4         SHARP MZ-2500 Emulator 'EmuZ-2500'
5
6         Author : Takeda.Toshiya
7         Date   : 2006.12.04 -
8
9         [ cmt ]
10 */
11
12 #include "cmt.h"
13 #include "../datarec.h"
14 #include "../i8255.h"
15
16 #define EVENT_FREW      0
17 #define EVENT_FFWD      1
18 #define EVENT_FWD       2
19 #define EVENT_STOP      3
20 #define EVENT_EJECT     4
21 #define EVENT_APSS      5
22 #define EVENT_IPL       6
23
24 #define PERIOD_IPL_SIGNAL       100
25 //#define PERIOD_CMT_SIGNAL     300000
26 #define PERIOD_CMT_SIGNAL       1000
27
28 namespace MZ2500 {
29
30 void CMT::initialize()
31 {
32         pa = pc = 0xff;
33         play = rec = false;
34         now_play = now_rewind = false;
35 }
36
37 void CMT::reset()
38 {
39         register_id_frew = -1;
40         register_id_ffwd = -1;
41         register_id_fwd = -1;
42         register_id_stop = -1;
43         register_id_eject = -1;
44 #ifndef _MZ80B
45         register_id_apss = -1;
46         now_apss = false;
47 #endif
48         register_id_ipl = -1;
49         close_tape();
50 }
51
52 void CMT::fast_forward()
53 {
54         if(play) {
55                 d_drec->set_ff_rew(1);
56                 d_drec->set_remote(true);
57         }
58         now_play = now_rewind = false;
59 }
60
61 void CMT::fast_rewind()
62 {
63         if(play) {
64                 d_drec->set_ff_rew(-1);
65                 d_drec->set_remote(true);
66         }
67         now_rewind = play;
68         now_play = false;
69 }
70
71 void CMT::forward()
72 {
73         if(play || rec) {
74                 d_drec->set_ff_rew(0);
75                 d_drec->set_remote(true);
76         }
77         now_play = (play || rec);
78         now_rewind = false;
79 }
80
81 void CMT::stop()
82 {
83         if(play || rec) {
84                 d_drec->set_remote(false);
85         }
86         now_play = now_rewind = false;
87         d_pio->write_signal(SIG_I8255_PORT_B, 0, 0x40);
88 }
89
90 void CMT::write_signal(int id, uint32_t data, uint32_t mask)
91 {
92         if(id == SIG_CMT_PIO_PA) {
93 #ifndef _MZ80B
94                 if((pa & 1) && !(data & 1)) {
95                         fast_rewind();
96                         now_apss = ((pa & 0x80) == 0);
97 //                      register_event(this, EVENT_FREW, PERIOD_CMT_SIGNAL, false, &register_id_frew);
98 //                      now_apss_tmp = ((pa & 0x80) == 0);
99 //              } else if(!(pa & 1) && (data & 1)) {
100 //                      if(register_id_frew != -1) {
101 //                              cancel_event(this, register_id_frew);
102 //                              register_id_frew = -1;
103 //                      }
104                 }
105                 if((pa & 2) && !(data & 2)) {
106                         fast_forward();
107                         now_apss = ((pa & 0x80) == 0);
108 //                      register_event(this, EVENT_FFWD, PERIOD_CMT_SIGNAL, false, &register_id_ffwd);
109 //                      now_apss_tmp = ((pa & 0x80) == 0);
110 //              } else if(!(pa & 2) && (data & 2)) {
111 //                      if(register_id_ffwd != -1) {
112 //                              cancel_event(this, register_id_ffwd);
113 //                              register_id_ffwd = -1;
114 //                      }
115                 }
116                 if((pa & 4) && !(data & 4)) {
117                         forward();
118                         now_apss = false;
119 //                      register_event(this, EVENT_FWD, PERIOD_CMT_SIGNAL, false, &register_id_fwd);
120 //              } else if(!(pa & 4) && (data & 4)) {
121 //                      if(register_id_fwd != -1) {
122 //                              cancel_event(this, register_id_fwd);
123 //                              register_id_fwd = -1;
124 //                      }
125                 }
126                 if((pa & 8) && !(data & 8)) {
127                         stop();
128                         // stop apss
129                         if(register_id_apss != -1) {
130                                 cancel_event(this, register_id_apss);
131                                 register_id_apss = -1;
132                         }
133                         now_apss = false;
134 //                      register_event(this, EVENT_STOP, PERIOD_CMT_SIGNAL, false, &register_id_stop);
135 //              } else if(!(pa & 8) && (data & 8)) {
136 //                      if(register_id_stop != -1) {
137 //                              cancel_event(this, register_id_stop);
138 //                              register_id_stop = -1;
139 //                      }
140                 }
141 #else
142                 if(!(pa & 1) && (data & 1)) {
143                         if(data & 2) {
144                                 fast_forward();
145 //                              register_event(this, EVENT_FFWD, PERIOD_CMT_SIGNAL, false, &register_id_ffwd);
146                         } else {
147                                 fast_rewind();
148 //                              register_event(this, EVENT_FREW, PERIOD_CMT_SIGNAL, false, &register_id_frew);
149                         }
150 //              } else if((pa & 1) && !(data & 1)) {
151 //                      if(register_id_ffwd != -1) {
152 //                              cancel_event(this, register_id_ffwd);
153 //                              register_id_ffwd = -1;
154 //                      }
155 //                      if(register_id_frew != -1) {
156 //                              cancel_event(this, register_id_frew);
157 //                              register_id_frew = -1;
158 //                      }
159                 }
160                 if(!(pa & 4) && (data & 4)) {
161                         forward();
162 //                      register_event(this, EVENT_FWD, PERIOD_CMT_SIGNAL, false, &register_id_fwd);
163 //              } else if((pa & 4) && !(data & 4)) {
164 //                      if(register_id_fwd != -1) {
165 //                              cancel_event(this, register_id_fwd);
166 //                              register_id_fwd = -1;
167 //                      }
168                 }
169                 if(!(pa & 8) && (data & 8)) {
170                         stop();
171 //                      register_event(this, EVENT_STOP, PERIOD_CMT_SIGNAL, false, &register_id_stop);
172 //              } else if((pa & 8) && !(data & 8)) {
173 //                      if(register_id_stop != -1) {
174 //                              cancel_event(this, register_id_stop);
175 //                              register_id_stop = -1;
176 //                      }
177                 }
178 #endif
179                 pa = data;
180         } else if(id == SIG_CMT_PIO_PC) {
181                 if(!(pc & 2) && (data & 2)) {
182                         vm->special_reset();
183                 }
184 #ifdef _MZ2500
185                 if(!(pc & 8) && (data & 8)) {
186                         vm->reset();
187                 }
188 #else
189                 if((pc & 8) && !(data & 8)) {
190                         register_event(this, EVENT_IPL, PERIOD_IPL_SIGNAL, false, &register_id_ipl);
191                 } else if(!(pc & 8) && (data & 8)) {
192                         if(register_id_ipl != -1) {
193                                 cancel_event(this, register_id_ipl);
194                                 register_id_ipl = -1;
195                         }
196                 }
197 #endif
198                 if((pc & 0x10) && !(data & 0x10)) {
199                         register_event(this, EVENT_EJECT, PERIOD_CMT_SIGNAL, false, &register_id_eject);
200                 } else if(!(pc & 0x10) && (data & 0x10)) {
201                         if(register_id_eject != -1) {
202                                 cancel_event(this, register_id_eject);
203                                 register_id_eject = -1;
204                         }
205                 }
206                 d_drec->write_signal(SIG_DATAREC_MIC, data, 0x80);
207                 pc = data;
208         } else if(id == SIG_CMT_OUT) {
209 #ifndef _MZ80B
210                 if(now_apss) {
211                         if((data & mask) && register_id_apss == -1) {
212                                 register_event(this, EVENT_APSS, 350000, false, &register_id_apss);
213                                 d_pio->write_signal(SIG_I8255_PORT_B, 0x40, 0x40);
214                         }
215                 } else
216 #endif
217                 if(now_play) {
218                         d_pio->write_signal(SIG_I8255_PORT_B, (data & mask) ? 0x40 : 0, 0x40);
219                 }
220         } else if(id == SIG_CMT_REMOTE) {
221                 d_pio->write_signal(SIG_I8255_PORT_B, (data & mask) ? 0 : 8, 8);
222         } else if(id == SIG_CMT_END) {
223                 if((data & mask) && now_play) {
224 #ifndef _MZ80B
225                         if(!(pa & 0x20)) {
226                                 fast_rewind();
227                         }
228 #endif
229                         now_play = false;
230                 }
231         } else if(id == SIG_CMT_TOP) {
232                 if((data & mask) && now_rewind) {
233 #ifndef _MZ80B
234                         if(!(pa & 0x40)) {
235                                 forward();
236                         }
237 #endif
238                         now_rewind = false;
239                 }
240         }
241 }
242
243 void CMT::event_callback(int event_id, int err)
244 {
245         if(event_id == EVENT_FREW) {
246                 fast_rewind();
247 #ifndef _MZ80B
248                 now_apss = now_apss_tmp;
249 #endif
250                 register_id_frew = -1;
251         } else if(event_id == EVENT_FFWD) {
252                 fast_forward();
253 #ifndef _MZ80B
254                 now_apss = now_apss_tmp;
255 #endif
256                 register_id_ffwd = -1;
257         } else if(event_id == EVENT_FWD) {
258                 forward();
259 #ifndef _MZ80B
260 //              if(register_id_apss != -1) {
261 //                      cancel_event(this, register_id_apss);
262 //                      register_id_apss = -1;
263 //              }
264                 now_apss = false;
265 #endif
266                 register_id_fwd = -1;
267         } else if(event_id == EVENT_STOP) {
268                 stop();
269 #ifndef _MZ80B
270                 if(register_id_apss != -1) {
271                         cancel_event(this, register_id_apss);
272                         register_id_apss = -1;
273                 }
274                 now_apss = false;
275 #endif
276                 register_id_stop = -1;
277         } else if(event_id == EVENT_EJECT) {
278                 emu->close_tape(0);
279                 register_id_eject = -1;
280 #ifndef _MZ80B
281         } else if(event_id == EVENT_APSS) {
282                 d_pio->write_signal(SIG_I8255_PORT_B, 0, 0x40);
283                 register_id_apss = -1;
284 #endif
285         } else if(event_id == EVENT_IPL) {
286                 vm->reset();
287                 register_id_ipl = -1;
288         }
289 }
290
291 void CMT::play_tape(bool value)
292 {
293         play = value;
294         rec = false;
295         d_pio->write_signal(SIG_I8255_PORT_B, play ? 0x10 : 0x30, 0x30);
296 }
297
298 void CMT::rec_tape(bool value)
299 {
300         play = false;
301         rec = value;
302         d_pio->write_signal(SIG_I8255_PORT_B, rec ? 0 : 0x30, 0x30);
303 }
304
305 void CMT::close_tape()
306 {
307         play = rec = false;
308         now_play = now_rewind = false;
309         d_pio->write_signal(SIG_I8255_PORT_B, 0x30, 0x30);
310         d_pio->write_signal(SIG_I8255_PORT_B, 0, 0x40);
311         
312 #ifndef _MZ80B
313         if(register_id_apss != -1) {
314                 cancel_event(this, register_id_apss);
315                 register_id_apss = -1;
316         }
317 #endif
318 }
319
320 #define STATE_VERSION   1
321
322 bool CMT::process_state(FILEIO* state_fio, bool loading)
323 {
324         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
325                 return false;
326         }
327         if(!state_fio->StateCheckInt32(this_device_id)) {
328                 return false;
329         }
330         state_fio->StateUint8(pa);
331         state_fio->StateUint8(pc);
332         state_fio->StateBool(play);
333         state_fio->StateBool(rec);
334         state_fio->StateBool(now_play);
335         state_fio->StateBool(now_rewind);
336         state_fio->StateInt32(register_id_frew);
337         state_fio->StateInt32(register_id_ffwd);
338         state_fio->StateInt32(register_id_fwd);
339         state_fio->StateInt32(register_id_stop);
340         state_fio->StateInt32(register_id_eject);
341 #ifndef _MZ80B
342         state_fio->StateInt32(register_id_apss);
343         state_fio->StateBool(now_apss);
344         state_fio->StateBool(now_apss_tmp);
345 #endif
346         state_fio->StateInt32(register_id_ipl);
347         return true;
348 }
349
350 }