2 NEC PC-8201 Emulator 'ePC-8201'
4 Author : Takeda.Toshiya
11 #include "../../fileio.h"
22 wav_chunk_t riff_chunk;
24 wav_chunk_t fmt_chunk;
34 #define SAMPLE_RATE 48000
36 void CMT::initialize()
54 void CMT::write_buffer(uint8 value, int samples)
57 for(int i = 0; i < samples; i++) {
58 buffer[bufcnt++] = value;
59 if(bufcnt == sizeof(buffer)) {
60 fio->Fwrite(buffer, sizeof(buffer), 1);
65 value = (value > 128) ? 0x80 : 0;
67 int s = min(samples, 0x7f);
69 buffer[bufcnt++] = value | s;
70 if(bufcnt == sizeof(buffer)) {
71 fio->Fwrite(buffer, sizeof(buffer), 1);
78 void CMT::put_signal()
81 uint32 clock = passed_clock(prev_clock);
82 if(prev_signal == 1) {
84 int count = (int)(1200.0 * (double)clock / (double)CPU_CLOCKS + 0.5) * 2;
85 for(int i = 0; i < count; i++) {
86 write_buffer(0xff, SAMPLE_RATE / 2400 / 2);
87 write_buffer(0x00, SAMPLE_RATE / 2400 / 2);
89 } else if(prev_signal == -1) {
91 int count = (int)(1200.0 * (double)clock / (double)CPU_CLOCKS + 0.5);
92 for(int i = 0; i < count; i++) {
93 write_buffer(0xff, SAMPLE_RATE / 1200 / 2);
94 write_buffer(0x00, SAMPLE_RATE / 1200 / 2);
97 write_buffer(0x80, SAMPLE_RATE * clock / CPU_CLOCKS);
102 void CMT::write_signal(int id, uint32 data, uint32 mask)
104 bool next = ((data & mask) != 0);
106 if(id == SIG_CMT_REMOTE) {
107 if(!remote && next) {
110 prev_clock = current_clock();
111 } else if(remote && !next) {
116 } else if(id == SIG_CMT_SOD) {
118 request_skip_frames();
121 prev_signal = next ? 1 : -1;
122 prev_clock = current_clock();
126 void CMT::rec_tape(_TCHAR* file_path)
130 if(fio->Fopen(file_path, FILEIO_WRITE_BINARY)) {
131 _tcscpy_s(rec_file_path, _MAX_PATH, file_path);
132 if(check_file_extension(file_path, _T(".wav"))) {
133 uint8 dummy[sizeof(wav_header_t) + sizeof(wav_chunk_t)];
134 memset(dummy, 0, sizeof(dummy));
135 fio->Fwrite(dummy, sizeof(dummy), 1);
143 void CMT::close_tape()
148 fio->Fwrite(buffer, bufcnt, 1);
151 uint32 length = fio->Ftell();
153 wav_header_t wav_header;
154 wav_chunk_t wav_chunk;
156 memcpy(wav_header.riff_chunk.id, "RIFF", 4);
157 wav_header.riff_chunk.size = length - 8;
158 memcpy(wav_header.wave, "WAVE", 4);
159 memcpy(wav_header.fmt_chunk.id, "fmt ", 4);
160 wav_header.fmt_chunk.size = 16;
161 wav_header.format_id = 1;
162 wav_header.channels = 1;
163 wav_header.sample_rate = SAMPLE_RATE;
164 wav_header.data_speed = SAMPLE_RATE;
165 wav_header.block_size = 1;
166 wav_header.sample_bits = 8;
168 memcpy(wav_chunk.id, "data", 4);
169 wav_chunk.size = length - sizeof(wav_header) - sizeof(wav_chunk);
171 fio->Fseek(0, FILEIO_SEEK_SET);
172 fio->Fwrite(&wav_header, sizeof(wav_header), 1);
173 fio->Fwrite(&wav_chunk, sizeof(wav_chunk), 1);
177 is_wav = rec = false;
180 #define STATE_VERSION 1
182 void CMT::save_state(FILEIO* state_fio)
184 state_fio->FputUint32(STATE_VERSION);
185 state_fio->FputInt32(this_device_id);
187 state_fio->FputBool(is_wav);
188 state_fio->FputBool(rec);
189 state_fio->FputBool(remote);
190 state_fio->Fwrite(rec_file_path, sizeof(rec_file_path), 1);
191 if(rec && fio->IsOpened()) {
192 int length_tmp = (int)fio->Ftell();
193 fio->Fseek(0, FILEIO_SEEK_SET);
194 state_fio->FputInt32(length_tmp);
195 while(length_tmp != 0) {
196 uint8 buffer_tmp[1024];
197 int length_rw = min(length_tmp, sizeof(buffer_tmp));
198 fio->Fread(buffer_tmp, length_rw, 1);
199 state_fio->Fwrite(buffer_tmp, length_rw, 1);
200 length_tmp -= length_rw;
203 state_fio->FputInt32(0);
205 state_fio->FputInt32(bufcnt);
206 state_fio->Fwrite(buffer, sizeof(buffer), 1);
207 state_fio->FputInt32(prev_signal);
208 state_fio->FputUint32(prev_clock);
211 bool CMT::load_state(FILEIO* state_fio)
215 if(state_fio->FgetUint32() != STATE_VERSION) {
218 if(state_fio->FgetInt32() != this_device_id) {
221 is_wav = state_fio->FgetBool();
222 rec = state_fio->FgetBool();
223 remote = state_fio->FgetBool();
224 state_fio->Fread(rec_file_path, sizeof(rec_file_path), 1);
225 int length_tmp = state_fio->FgetInt32();
227 fio->Fopen(rec_file_path, FILEIO_READ_WRITE_NEW_BINARY);
228 while(length_tmp != 0) {
229 uint8 buffer_tmp[1024];
230 int length_rw = min(length_tmp, sizeof(buffer_tmp));
231 state_fio->Fread(buffer_tmp, length_rw, 1);
232 if(fio->IsOpened()) {
233 fio->Fwrite(buffer_tmp, length_rw, 1);
235 length_tmp -= length_rw;
238 bufcnt = state_fio->FgetInt32();
239 state_fio->Fread(buffer, sizeof(buffer), 1);
240 prev_signal = state_fio->FgetInt32();
241 prev_clock = state_fio->FgetUint32();