OSDN Git Service

8da4c8665a8d55606ebfd44f5345f7eb614a3335
[csp-qt/common_source_project-fm7.git] / source / src / vm / tk80bs / cmt.cpp
1 /*
2         NEC TK-80BS (COMPO BS/80) Emulator 'eTK-80BS'
3         NEC TK-80 Emulator 'eTK-80'
4
5         Author : Takeda.Toshiya
6         Date   : 2008.08.26 -
7
8         [ cmt ]
9 */
10
11 #include "cmt.h"
12 #include "../datarec.h"
13 #if defined(_TK80BS)
14 #include "../i8251.h"
15 #endif
16 #include "../i8255.h"
17
18 #define EVENT_PULSE     0
19
20 void CMT::initialize()
21 {
22         mic = ear = pulse = false;
23         pulse_count = 0;
24         register_event(this, EVENT_PULSE, 1000000 / 4000, true, NULL);
25         
26 #if defined(_TK80BS)
27         fio = new FILEIO();
28         play = rec = false;
29 #endif
30 }
31
32 #if defined(_TK80BS)
33 void CMT::release()
34 {
35         release_tape();
36         delete fio;
37 }
38
39 void CMT::reset()
40 {
41         close_tape();
42         play = rec = false;
43 }
44 #endif
45
46 void CMT::write_signal(int id, uint32_t data, uint32_t mask)
47 {
48         if(id == SIG_CMT_MIC) {
49                 // recv mic signal from pio
50                 mic = ((data & mask) != 0);
51         } else if(id == SIG_CMT_EAR) {
52                 // recv ear signal from datarec
53                 bool next = ((data & mask) != 0);
54                 if(ear != next) {
55                         pulse_count = 0;
56                         ear = next;
57                 }
58 #if defined(_TK80BS)
59         } else if(id == SIG_CMT_OUT) {
60                 // recv data from sio
61                 if(rec) {
62                         buffer[bufcnt++] = data & mask;
63                         if(bufcnt >= BUFFER_SIZE) {
64                                 fio->Fwrite(buffer, bufcnt, 1);
65                                 bufcnt = 0;
66                         }
67                 }
68 #endif
69         }
70 }
71
72 void CMT::event_callback(int event_id, int err)
73 {
74         // send mic signal to datarec
75         d_drec->write_signal(SIG_DATAREC_MIC, (mic && pulse) ? 1 : 0, 1);
76         pulse = !pulse;
77         
78         // send ear signal to pio
79         if(pulse_count > 4) {
80                 // ear signal is not changed for 1 msec or more
81                 d_pio->write_signal(SIG_I8255_PORT_B, 0, 1);
82         } else {
83                 d_pio->write_signal(SIG_I8255_PORT_B, 1, 1);
84                 pulse_count++;
85         }
86 }
87
88 #if defined(_TK80BS)
89 void CMT::play_tape(const _TCHAR* file_path)
90 {
91         close_tape();
92         
93         if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
94                 fio->Fseek(0, FILEIO_SEEK_END);
95                 int size = (fio->Ftell() + 9) & (BUFFER_SIZE - 1);
96                 fio->Fseek(0, FILEIO_SEEK_SET);
97                 memset(buffer, 0, sizeof(buffer));
98                 fio->Fread(buffer, sizeof(buffer), 1);
99                 fio->Fclose();
100                 
101                 // send data to sio
102                 // this implement does not care the sio buffer size... :-(
103                 for(int i = 0; i < size; i++) {
104                         d_sio->write_signal(SIG_I8251_RECV, buffer[i], 0xff);
105                 }
106                 play = true;
107         }
108 }
109
110 void CMT::rec_tape(const _TCHAR* file_path)
111 {
112         close_tape();
113         
114         if(fio->Fopen(file_path, FILEIO_WRITE_BINARY)) {
115                 my_tcscpy_s(rec_file_path, _MAX_PATH, file_path);
116                 bufcnt = 0;
117                 rec = true;
118         }
119 }
120
121 void CMT::close_tape()
122 {
123         // close file
124         release_tape();
125         
126         // clear sio buffer
127         d_sio->write_signal(SIG_I8251_CLEAR, 0, 0);
128 }
129
130 void CMT::release_tape()
131 {
132         // close file
133         if(fio->IsOpened()) {
134                 if(rec && bufcnt) {
135                         fio->Fwrite(buffer, bufcnt, 1);
136                 }
137                 fio->Fclose();
138         }
139         play = rec = false;
140 }
141 #endif
142
143 #define STATE_VERSION   2
144
145 #include "../../statesub.h"
146
147 void CMT::decl_state()
148 {
149         enter_decl_state(STATE_VERSION);
150         
151         DECL_STATE_ENTRY_BOOL(mic);
152         DECL_STATE_ENTRY_BOOL(ear);
153         DECL_STATE_ENTRY_BOOL(pulse);
154         DECL_STATE_ENTRY_INT32(pulse_count);
155 #if defined(_TK80BS)
156         DECL_STATE_ENTRY_BOOL(play);
157         DECL_STATE_ENTRY_BOOL(rec);
158         DECL_STATE_ENTRY_STRING(rec_file_path, sizeof(rec_file_path) / sizeof(_TCHAR));
159
160         DECL_STATE_ENTRY_CMT_RECORDING(fio, rec, rec_file_path);
161
162         DECL_STATE_ENTRY_INT32(bufcnt);
163         DECL_STATE_ENTRY_1D_ARRAY(buffer, sizeof(buffer));
164 #endif
165         leave_decl_state();
166 }
167
168 void CMT::save_state(FILEIO* state_fio)
169 {
170         if(state_entry != NULL) {
171                 state_entry->save_state(state_fio);
172         }
173 //      state_fio->FputUint32(STATE_VERSION);
174 //      state_fio->FputInt32(this_device_id);
175         
176 //      state_fio->FputBool(mic);
177 //      state_fio->FputBool(ear);
178 //      state_fio->FputBool(pulse);
179 //      state_fio->FputInt32(pulse_count);
180 #if defined(_TK80BS)
181 //      state_fio->FputBool(play);
182 //      state_fio->FputBool(rec);
183 //      state_fio->Fwrite(rec_file_path, sizeof(rec_file_path), 1);
184 //      if(rec && fio->IsOpened()) {
185 //              int length_tmp = (int)fio->Ftell();
186 //              fio->Fseek(0, FILEIO_SEEK_SET);
187 //              state_fio->FputInt32(length_tmp);
188 //              while(length_tmp != 0) {
189 //                      uint8_t buffer_tmp[1024];
190 //                      int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
191 //                      fio->Fread(buffer_tmp, length_rw, 1);
192 //                      state_fio->Fwrite(buffer_tmp, length_rw, 1);
193 //                      length_tmp -= length_rw;
194 //              }
195 //      } else {
196 //              state_fio->FputInt32(0);
197 //      }
198 //      state_fio->FputInt32(bufcnt);
199 //      state_fio->Fwrite(buffer, sizeof(buffer), 1);
200 #endif
201 }
202
203 bool CMT::load_state(FILEIO* state_fio)
204 {
205         release_tape();
206         
207         bool mb = false;
208         if(state_entry != NULL) {
209                 mb = state_entry->load_state(state_fio);
210         }
211         if(!mb) {
212                 return false;
213         }
214 //      if(state_fio->FgetUint32() != STATE_VERSION) {
215 //              return false;
216 //      }
217 //      if(state_fio->FgetInt32() != this_device_id) {
218 //              return false;
219 //      }
220 //      mic = state_fio->FgetBool();
221 //      ear = state_fio->FgetBool();
222 //      pulse = state_fio->FgetBool();
223 //      pulse_count = state_fio->FgetInt32();
224 //#if defined(_TK80BS)
225 //      play = state_fio->FgetBool();
226 //      rec = state_fio->FgetBool();
227 //      state_fio->Fread(rec_file_path, sizeof(rec_file_path), 1);
228 //      int length_tmp = state_fio->FgetInt32();
229 //      if(rec) {
230 //              fio->Fopen(rec_file_path, FILEIO_READ_WRITE_NEW_BINARY);
231 //              while(length_tmp != 0) {
232 //                      uint8_t buffer_tmp[1024];
233 //                      int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
234 //                      state_fio->Fread(buffer_tmp, length_rw, 1);
235 //                      if(fio->IsOpened()) {
236 //                              fio->Fwrite(buffer_tmp, length_rw, 1);
237 //                      }
238 //                      length_tmp -= length_rw;
239 //              }
240 //      }
241 //      bufcnt = state_fio->FgetInt32();
242 //      state_fio->Fread(buffer, sizeof(buffer), 1);
243 //#endif
244         return true;
245 }
246
247 bool CMT::process_state(FILEIO* state_fio, bool loading)
248 {
249         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
250                 return false;
251         }
252         if(!state_fio->StateCheckInt32(this_device_id)) {
253                 return false;
254         }
255         state_fio->StateBool(mic);
256         state_fio->StateBool(ear);
257         state_fio->StateBool(pulse);
258         state_fio->StateInt32(pulse_count);
259 #if defined(_TK80BS)
260         state_fio->StateBool(play);
261         state_fio->StateBool(rec);
262         state_fio->StateBuffer(rec_file_path, sizeof(rec_file_path), 1);
263         if(loading) {
264                 int length_tmp = state_fio->FgetInt32_LE();
265                 if(rec) {
266                         fio->Fopen(rec_file_path, FILEIO_READ_WRITE_NEW_BINARY);
267                         while(length_tmp != 0) {
268                                 uint8_t buffer_tmp[1024];
269                                 int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
270                                 state_fio->Fread(buffer_tmp, length_rw, 1);
271                                 if(fio->IsOpened()) {
272                                         fio->Fwrite(buffer_tmp, length_rw, 1);
273                                 }
274                                 length_tmp -= length_rw;
275                         }
276                 }
277         } else {
278                 if(rec && fio->IsOpened()) {
279                         int length_tmp = (int)fio->Ftell();
280                         fio->Fseek(0, FILEIO_SEEK_SET);
281                         state_fio->FputInt32_LE(length_tmp);
282                         while(length_tmp != 0) {
283                                 uint8_t buffer_tmp[1024];
284                                 int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
285                                 fio->Fread(buffer_tmp, length_rw, 1);
286                                 state_fio->Fwrite(buffer_tmp, length_rw, 1);
287                                 length_tmp -= length_rw;
288                         }
289                 } else {
290                         state_fio->FputInt32_LE(0);
291                 }
292         }
293         state_fio->StateInt32(bufcnt);
294         state_fio->StateBuffer(buffer, sizeof(buffer), 1);
295 #endif
296         return true;
297 }