2 SONY SMC-70 Emulator 'eSMC-70'
3 SONY SMC-777 Emulator 'eSMC-777'
5 Author : Takeda.Toshiya
12 #include "../../emu.h"
13 #include "../device.h"
16 #include "../datarec.h"
18 #include "../hd46505.h"
19 #include "../mb8877.h"
21 #include "../msm58321.h"
24 #include "../pcm1bit.h"
26 #include "../sn76489an.h"
31 #include "../debugger.h"
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
43 first_device = last_device = NULL;
44 dummy = new DEVICE(this, emu); // must be 1st device
45 event = new EVENT(this, emu); // must be 2nd device
46 dummy->set_device_name(_T("1st Dummy"));
48 drec = new DATAREC(this, emu);
49 drec->set_context_noise_play(new NOISE(this, emu));
50 drec->set_context_noise_stop(new NOISE(this, emu));
51 drec->set_context_noise_fast(new NOISE(this, emu));
52 crtc = new HD46505(this, emu);
53 fdc = new MB8877(this, emu);
54 fdc->set_context_noise_seek(new NOISE(this, emu));
55 fdc->set_context_noise_head_down(new NOISE(this, emu));
56 fdc->set_context_noise_head_up(new NOISE(this, emu));
58 rtc = new MSM58321(this, emu);
60 pcm = new PCM1BIT(this, emu);
62 psg = new SN76489AN(this, emu);
64 cpu = new Z80(this, emu);
66 memory = new MEMORY(this, emu);
69 event->set_context_cpu(cpu);
70 event->set_context_sound(pcm);
72 event->set_context_sound(psg);
74 event->set_context_sound(drec);
75 event->set_context_sound(fdc->get_context_noise_seek());
76 event->set_context_sound(fdc->get_context_noise_head_down());
77 event->set_context_sound(fdc->get_context_noise_head_up());
78 event->set_context_sound(drec->get_context_noise_play());
79 event->set_context_sound(drec->get_context_noise_stop());
80 event->set_context_sound(drec->get_context_noise_fast());
82 // Sound:: Force realtime rendering. This is temporally fix. 20161024 K.O
83 //pcm->set_realtime_render(true);
85 drec->set_context_ear(memory, SIG_MEMORY_DATAREC_IN, 1);
86 crtc->set_context_disp(memory, SIG_MEMORY_CRTC_DISP, 1);
87 crtc->set_context_vsync(memory, SIG_MEMORY_CRTC_VSYNC, 1);
88 fdc->set_context_drq(memory, SIG_MEMORY_FDC_DRQ, 1);
89 fdc->set_context_irq(memory, SIG_MEMORY_FDC_IRQ, 1);
91 rtc->set_context_data(memory, SIG_MEMORY_RTC_DATA, 0x0f, 0);
92 rtc->set_context_busy(memory, SIG_MEMORY_RTC_BUSY, 1);
95 memory->set_context_cpu(cpu);
96 memory->set_context_crtc(crtc, crtc->get_regs());
97 memory->set_context_drec(drec);
98 memory->set_context_fdc(fdc);
99 memory->set_context_pcm(pcm);
101 memory->set_context_rtc(rtc);
102 #elif defined(_SMC777)
103 memory->set_context_psg(psg);
107 cpu->set_context_mem(memory);
108 cpu->set_context_io(memory);
109 cpu->set_context_intr(dummy);
111 cpu->set_context_debugger(new DEBUGGER(this, emu));
114 // initialize all devices
115 #if defined(__GIT_REPO_VERSION)
116 strncpy(_git_revision, __GIT_REPO_VERSION, sizeof(_git_revision) - 1);
118 for(DEVICE* device = first_device; device; device = device->next_device) {
119 device->initialize();
122 for(int i = 0; i < MAX_DRIVE; i++) {
123 fdc->set_drive_type(i, DRIVE_TYPE_2DD); // 1DD
124 fdc->set_drive_rpm(i, 600);
126 fdc->write_signal(SIG_MB8877_MOTOR, 1, 1);
131 // delete all devices
132 for(DEVICE* device = first_device; device;) {
133 DEVICE *next_device = device->next_device;
136 device = next_device;
140 DEVICE* VM::get_device(int id)
142 for(DEVICE* device = first_device; device; device = device->next_device) {
143 if(device->this_device_id == id) {
150 // ----------------------------------------------------------------------------
151 // drive virtual machine
152 // ----------------------------------------------------------------------------
157 for(DEVICE* device = first_device; device; device = device->next_device) {
160 memory->warm_start = false;
163 void VM::special_reset()
166 for(DEVICE* device = first_device; device; device = device->next_device) {
169 memory->warm_start = true;
177 double VM::get_frame_rate()
179 return event->get_frame_rate();
182 // ----------------------------------------------------------------------------
184 // ----------------------------------------------------------------------------
187 DEVICE *VM::get_cpu(int index)
196 // ----------------------------------------------------------------------------
198 // ----------------------------------------------------------------------------
200 void VM::draw_screen()
202 memory->draw_screen();
205 // ----------------------------------------------------------------------------
207 // ----------------------------------------------------------------------------
209 void VM::initialize_sound(int rate, int samples)
211 // init sound manager
212 event->initialize_sound(rate, samples);
215 pcm->initialize_sound(rate, 5000);
217 psg->initialize_sound(rate, CPU_CLOCKS, 5000);
221 uint16_t* VM::create_sound(int* extra_frames)
223 return event->create_sound(extra_frames);
226 int VM::get_sound_buffer_ptr()
228 return event->get_sound_buffer_ptr();
231 #ifdef USE_SOUND_VOLUME
232 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
236 psg->set_volume(0, decibel_l, decibel_r);
240 pcm->set_volume(0, decibel_l, decibel_r);
241 } else if(ch-- == 0) {
242 drec->set_volume(0, decibel_l, decibel_r);
243 } else if(ch-- == 0) {
244 fdc->get_context_noise_seek()->set_volume(0, decibel_l, decibel_r);
245 fdc->get_context_noise_head_down()->set_volume(0, decibel_l, decibel_r);
246 fdc->get_context_noise_head_up()->set_volume(0, decibel_l, decibel_r);
247 } else if(ch-- == 0) {
248 drec->get_context_noise_play()->set_volume(0, decibel_l, decibel_r);
249 drec->get_context_noise_stop()->set_volume(0, decibel_l, decibel_r);
250 drec->get_context_noise_fast()->set_volume(0, decibel_l, decibel_r);
255 // ----------------------------------------------------------------------------
257 // ----------------------------------------------------------------------------
259 void VM::key_down(int code, bool repeat)
262 memory->key_down_up(code, true);
266 void VM::key_up(int code)
268 memory->key_down_up(code, false);
271 bool VM::get_caps_locked()
273 return memory->get_caps_locked();
276 bool VM::get_kana_locked()
278 return memory->get_kana_locked();
281 // ----------------------------------------------------------------------------
283 // ----------------------------------------------------------------------------
285 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
287 fdc->open_disk(drv, file_path, bank);
290 void VM::close_floppy_disk(int drv)
292 fdc->close_disk(drv);
295 bool VM::is_floppy_disk_inserted(int drv)
297 return fdc->is_disk_inserted(drv);
300 void VM::is_floppy_disk_protected(int drv, bool value)
302 fdc->is_disk_protected(drv, value);
305 bool VM::is_floppy_disk_protected(int drv)
307 return fdc->is_disk_protected(drv);
310 uint32_t VM::is_floppy_disk_accessed()
312 return fdc->read_signal(0);
315 void VM::play_tape(int drv, const _TCHAR* file_path)
317 drec->play_tape(file_path);
318 // drec->set_remote(true);
321 void VM::rec_tape(int drv, const _TCHAR* file_path)
323 drec->rec_tape(file_path);
324 // drec->set_remote(true);
327 void VM::close_tape(int drv)
332 // drec->set_remote(false);
335 bool VM::is_tape_inserted(int drv)
337 return drec->is_tape_inserted();
340 bool VM::is_tape_playing(int drv)
342 return drec->is_tape_playing();
345 bool VM::is_tape_recording(int drv)
347 return drec->is_tape_recording();
350 int VM::get_tape_position(int drv)
352 return drec->get_tape_position();
355 const _TCHAR* VM::get_tape_message(int drv)
357 return drec->get_message();
360 void VM::push_play(int drv)
363 drec->set_remote(true);
366 void VM::push_stop(int drv)
368 drec->set_remote(false);
371 void VM::push_fast_forward(int drv)
374 drec->set_remote(true);
377 void VM::push_fast_rewind(int drv)
379 drec->set_ff_rew(-1);
380 drec->set_remote(true);
383 bool VM::is_frame_skippable()
385 return event->is_frame_skippable();
388 void VM::update_config()
390 for(DEVICE* device = first_device; device; device = device->next_device) {
391 device->update_config();
395 #define STATE_VERSION 4
397 #include "../../statesub.h"
398 #include "../../qt/gui/csp_logger.h"
399 extern CSP_Logger DLL_PREFIX_I *csp_logger;
401 void VM::decl_state(void)
404 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::SMC_70_HEAD")), csp_logger);
405 #elif defined(_SMC777)
406 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::SMC_777_HEAD")), csp_logger);
408 state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::SMC_70_SERIES_HEAD")), csp_logger);
410 for(DEVICE* device = first_device; device; device = device->next_device) {
411 device->decl_state();
415 void VM::save_state(FILEIO* state_fio)
417 //state_fio->FputUint32(STATE_VERSION);
419 if(state_entry != NULL) {
420 state_entry->save_state(state_fio);
422 for(DEVICE* device = first_device; device; device = device->next_device) {
423 device->save_state(state_fio);
427 bool VM::load_state(FILEIO* state_fio)
429 //if(state_fio->FgetUint32() != STATE_VERSION) {
433 if(state_entry != NULL) {
434 mb = state_entry->load_state(state_fio);
437 emu->out_debug_log("INFO: HEADER DATA ERROR");
440 for(DEVICE* device = first_device; device; device = device->next_device) {
441 if(!device->load_state(state_fio)) {