2 NEC PC-8201 Emulator 'ePC-8201'
4 Author : Takeda.Toshiya
12 #define SAMPLE_RATE 48000
14 void CMT::initialize()
32 void CMT::write_buffer(uint8_t value, int samples)
35 for(int i = 0; i < samples; i++) {
36 buffer[bufcnt++] = value;
37 if(bufcnt == sizeof(buffer)) {
38 fio->Fwrite(buffer, sizeof(buffer), 1);
43 value = (value > 128) ? 0x80 : 0;
45 int s = min(samples, 0x7f);
47 buffer[bufcnt++] = value | s;
48 if(bufcnt == sizeof(buffer)) {
49 fio->Fwrite(buffer, sizeof(buffer), 1);
56 void CMT::put_signal()
59 uint32_t clock = get_passed_clock(prev_clock);
60 if(prev_signal == 1) {
62 int count = (int)(1200.0 * (double)clock / (double)CPU_CLOCKS + 0.5) * 2;
63 for(int i = 0; i < count; i++) {
64 write_buffer(0xff, SAMPLE_RATE / 2400 / 2);
65 write_buffer(0x00, SAMPLE_RATE / 2400 / 2);
67 } else if(prev_signal == -1) {
69 int count = (int)(1200.0 * (double)clock / (double)CPU_CLOCKS + 0.5);
70 for(int i = 0; i < count; i++) {
71 write_buffer(0xff, SAMPLE_RATE / 1200 / 2);
72 write_buffer(0x00, SAMPLE_RATE / 1200 / 2);
75 write_buffer(0x80, SAMPLE_RATE * clock / CPU_CLOCKS);
80 void CMT::write_signal(int id, uint32_t data, uint32_t mask)
82 bool next = ((data & mask) != 0);
84 if(id == SIG_CMT_REMOTE) {
88 prev_clock = get_current_clock();
89 } else if(remote && !next) {
94 } else if(id == SIG_CMT_SOD) {
96 request_skip_frames();
99 prev_signal = next ? 1 : -1;
100 prev_clock = get_current_clock();
104 void CMT::rec_tape(const _TCHAR* file_path)
108 if(fio->Fopen(file_path, FILEIO_WRITE_BINARY)) {
109 my_tcscpy_s(rec_file_path, _MAX_PATH, file_path);
110 if(check_file_extension(file_path, _T(".wav"))) {
111 write_dummy_wav_header((void *)fio);
119 void CMT::close_tape()
124 fio->Fwrite(buffer, bufcnt, 1);
127 uint32_t length = fio->Ftell();
128 wav_header_t wav_header;
129 wav_chunk_t wav_chunk;
132 pair_t __riff_chunk_size;
133 pair_t __fmt_chunk_size;
134 pair_t __wav_chunk_size;
137 pair_t __sample_rate;
138 pair16_t __block_size;
139 pair16_t __sample_bits;
141 __riff_chunk_size.d = length - 8;
142 __fmt_chunk_size.d = 16;
145 __sample_rate.d = SAMPLE_RATE;
149 memcpy(wav_header.riff_chunk.id, "RIFF", 4);
150 wav_header.riff_chunk.size = __riff_chunk_size.get_4bytes_le_to();
152 memcpy(wav_header.wave, "WAVE", 4);
153 memcpy(wav_header.fmt_chunk.id, "fmt ", 4);
154 wav_header.fmt_chunk.size = __riff_chunk_size.get_4bytes_le_to();
155 wav_header.format_id = __fmt_id.get_2bytes_le_to();
156 wav_header.channels = __channels.get_2byte_le_to();
157 wav_header.sample_rate = __sample_rate.get_4bytes_le_to();
158 wav_header.data_speed = __sample_rate.get_4bytes_le_to();
159 wav_header.block_size = __block_size.get_2bytes_le_to();
160 wav_header.sample_bits = __sample_bits_get_2bytes_le_to();
162 memcpy(wav_chunk.id, "data", 4);
163 __wav_chunk_size.d = length - sizeof(wav_header) - sizeof(wav_chunk);
164 wav_chunk.size = __wav_chunk_size.get_4bytes_le_to();
167 fio->Fseek(0, FILEIO_SEEK_SET);
168 fio->Fwrite(&wav_header, sizeof(wav_header), 1);
169 fio->Fwrite(&wav_chunk, sizeof(wav_chunk), 1);
171 if(set_wav_header(&wav_header, &wav_chunk, 1, SAMPLE_RATE, 8, length)) {
172 fio->Fseek(0, FILEIO_SEEK_SET);
173 fio->Fwrite(&wav_header, sizeof(wav_header), 1);
174 fio->Fwrite(&wav_chunk, sizeof(wav_chunk), 1);
180 is_wav = rec = false;
183 #define STATE_VERSION 1
185 #include "../../statesub.h"
187 void CMT::decl_state()
189 enter_decl_state(STATE_VERSION);
191 DECL_STATE_ENTRY_BOOL(is_wav);
192 DECL_STATE_ENTRY_BOOL(rec);
193 DECL_STATE_ENTRY_BOOL(remote);
194 DECL_STATE_ENTRY_STRING(rec_file_path, sizeof(rec_file_path));
195 DECL_STATE_ENTRY_CMT_RECORDING(fio, rec, rec_file_path);
197 DECL_STATE_ENTRY_INT32(bufcnt);
198 DECL_STATE_ENTRY_1D_ARRAY(buffer, sizeof(buffer));
199 DECL_STATE_ENTRY_INT32(prev_signal);
200 DECL_STATE_ENTRY_UINT32(prev_clock);
205 void CMT::save_state(FILEIO* state_fio)
207 if(state_entry != NULL) {
208 state_entry->save_state(state_fio);
210 // state_fio->FputUint32(STATE_VERSION);
211 // state_fio->FputInt32(this_device_id);
213 // state_fio->FputBool(is_wav);
214 // state_fio->FputBool(rec);
215 // state_fio->FputBool(remote);
216 // state_fio->Fwrite(rec_file_path, sizeof(rec_file_path), 1);
217 // if(rec && fio->IsOpened()) {
218 // int length_tmp = (int)fio->Ftell();
219 // fio->Fseek(0, FILEIO_SEEK_SET);
220 // state_fio->FputInt32(length_tmp);
221 // while(length_tmp != 0) {
222 // uint8_t buffer_tmp[1024];
223 // int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
224 // fio->Fread(buffer_tmp, length_rw, 1);
225 // state_fio->Fwrite(buffer_tmp, length_rw, 1);
226 // length_tmp -= length_rw;
229 // state_fio->FputInt32(0);
231 // state_fio->FputInt32(bufcnt);
232 // state_fio->Fwrite(buffer, sizeof(buffer), 1);
233 // state_fio->FputInt32(prev_signal);
234 // state_fio->FputUint32(prev_clock);
237 bool CMT::load_state(FILEIO* state_fio)
242 if(state_entry != NULL) {
243 mb = state_entry->load_state(state_fio);
248 // if(state_fio->FgetUint32() != STATE_VERSION) {
251 // if(state_fio->FgetInt32() != this_device_id) {
254 // is_wav = state_fio->FgetBool();
255 // rec = state_fio->FgetBool();
256 // remote = state_fio->FgetBool();
257 // state_fio->Fread(rec_file_path, sizeof(rec_file_path), 1);
258 // int length_tmp = state_fio->FgetInt32();
260 // fio->Fopen(rec_file_path, FILEIO_READ_WRITE_NEW_BINARY);
261 // while(length_tmp != 0) {
262 // uint8_t buffer_tmp[1024];
263 // int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
264 // state_fio->Fread(buffer_tmp, length_rw, 1);
265 // if(fio->IsOpened()) {
266 // fio->Fwrite(buffer_tmp, length_rw, 1);
268 // length_tmp -= length_rw;
271 // bufcnt = state_fio->FgetInt32();
272 // state_fio->Fread(buffer, sizeof(buffer), 1);
273 // prev_signal = state_fio->FgetInt32();
274 // prev_clock = state_fio->FgetUint32();
278 bool CMT::process_state(FILEIO* state_fio, bool loading)
280 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
283 if(!state_fio->StateCheckInt32(this_device_id)) {
286 state_fio->StateBool(is_wav);
287 state_fio->StateBool(rec);
288 state_fio->StateBool(remote);
289 state_fio->StateBuffer(rec_file_path, sizeof(rec_file_path), 1);
291 int length_tmp = state_fio->FgetInt32_LE();
293 fio->Fopen(rec_file_path, FILEIO_READ_WRITE_NEW_BINARY);
294 while(length_tmp != 0) {
295 uint8_t buffer_tmp[1024];
296 int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
297 state_fio->Fread(buffer_tmp, length_rw, 1);
298 if(fio->IsOpened()) {
299 fio->Fwrite(buffer_tmp, length_rw, 1);
301 length_tmp -= length_rw;
305 if(rec && fio->IsOpened()) {
306 int length_tmp = (int)fio->Ftell();
307 fio->Fseek(0, FILEIO_SEEK_SET);
308 state_fio->FputInt32_LE(length_tmp);
309 while(length_tmp != 0) {
310 uint8_t buffer_tmp[1024];
311 int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
312 fio->Fread(buffer_tmp, length_rw, 1);
313 state_fio->Fwrite(buffer_tmp, length_rw, 1);
314 length_tmp -= length_rw;
317 state_fio->FputInt32_LE(0);
320 state_fio->StateInt32(bufcnt);
321 state_fio->StateBuffer(buffer, sizeof(buffer), 1);
322 state_fio->StateInt32(prev_signal);
323 state_fio->StateUint32(prev_clock);