2 NEC PC-2001 Emulator 'ePC-2001'
5 Author : Takeda.Toshiya
12 #include "../../emu.h"
13 #include "../device.h"
16 #include "../datarec.h"
17 #include "../memory.h"
18 #include "../pcm1bit.h"
19 #include "../upd16434.h"
20 #include "../upd1990a.h"
21 #include "../upd7810.h"
24 #include "../debugger.h"
29 // ----------------------------------------------------------------------------
31 // ----------------------------------------------------------------------------
33 VM::VM(EMU* parent_emu) : emu(parent_emu)
36 first_device = last_device = NULL;
37 dummy = new DEVICE(this, emu); // must be 1st device
38 event = new EVENT(this, emu); // must be 2nd device
40 dummy->set_device_name(_T("1st Dummy"));
41 event->set_device_name(_T("EVENT"));
44 drec = new DATAREC(this, emu);
45 memory = new MEMORY(this, emu);
46 pcm = new PCM1BIT(this, emu);
47 lcd[0] = new UPD16434(this, emu);
48 lcd[0]->set_device_name(_T("uPD16434 LCD Controller #0"));
49 lcd[1] = new UPD16434(this, emu);
50 lcd[1]->set_device_name(_T("uPD16434 LCD Controller #1"));
51 lcd[2] = new UPD16434(this, emu);
52 lcd[2]->set_device_name(_T("uPD16434 LCD Controller #2"));
53 lcd[3] = new UPD16434(this, emu);
54 lcd[3]->set_device_name(_T("uPD16434 LCD Controller #3"));
55 rtc = new UPD1990A(this, emu);
56 cpu = new UPD7810(this, emu);
58 lcd[0]->set_device_name(_T("uPD16434 LCD CONTROLLER #1"));
59 lcd[1]->set_device_name(_T("uPD16434 LCD CONTROLLER #2"));
60 lcd[2]->set_device_name(_T("uPD16434 LCD CONTROLLER #3"));
61 lcd[3]->set_device_name(_T("uPD16434 LCD CONTROLLER #4"));
62 cpu->set_device_name(_T("CPU(uPD7810)"));
65 io = new IO(this, emu);
67 io->set_device_name(_T("I/O BUS"));
70 event->set_context_cpu(cpu);
71 event->set_context_sound(pcm);
72 event->set_context_sound(drec);
73 #if defined(USE_SOUND_FILES)
74 drec->load_sound_data(DATAREC_SNDFILE_RELAY_ON, _T("CMTPLAY.WAV"));
75 drec->load_sound_data(DATAREC_SNDFILE_RELAY_OFF, _T("CMTSTOP.WAV"));
76 drec->load_sound_data(DATAREC_SNDFILE_EJECT, _T("CMTEJECT.WAV"));
78 drec->set_context_ear(io, SIG_IO_DREC_IN, 1);
79 rtc->set_context_dout(io, SIG_IO_RTC_IN, 1);
80 cpu->set_context_to(pcm, SIG_PCM1BIT_SIGNAL, 1);
82 io->set_context_lcd(0, lcd[0]);
83 io->set_context_lcd(1, lcd[1]);
84 io->set_context_lcd(2, lcd[2]);
85 io->set_context_lcd(3, lcd[3]);
86 io->set_context_drec(drec);
87 io->set_context_rtc(rtc);
88 io->set_context_cpu(cpu);
91 memset(ram, 0xff, sizeof(ram));
92 // memset(ram, 0, sizeof(ram));
93 memset(rom1, 0xff, sizeof(rom1));
94 memset(rom2, 0xff, sizeof(rom2));
96 memory->read_bios(_T("0000-0FFF.ROM"), rom1, sizeof(rom1));
97 memory->read_bios(_T("2000-5FFF.ROM"), rom2, sizeof(rom2));
99 memory->set_memory_r(0x0000, 0x0fff, rom1);
100 memory->set_memory_r(0x2000, 0x5fff, rom2);
101 memory->set_memory_rw(0xb000, 0xffff, ram);
104 cpu->set_context_mem(memory);
105 cpu->set_context_io(io);
107 cpu->set_context_debugger(new DEBUGGER(this, emu));
110 // initialize all devices
111 for(DEVICE* device = first_device; device; device = device->next_device) {
112 device->initialize();
118 // delete all devices
119 for(DEVICE* device = first_device; device;) {
120 DEVICE *next_device = device->next_device;
123 device = next_device;
127 DEVICE* VM::get_device(int id)
129 for(DEVICE* device = first_device; device; device = device->next_device) {
130 if(device->this_device_id == id) {
137 // ----------------------------------------------------------------------------
138 // drive virtual machine
139 // ----------------------------------------------------------------------------
144 for(DEVICE* device = first_device; device; device = device->next_device) {
154 // ----------------------------------------------------------------------------
156 // ----------------------------------------------------------------------------
159 DEVICE *VM::get_cpu(int index)
168 // ----------------------------------------------------------------------------
170 // ----------------------------------------------------------------------------
172 void VM::draw_screen()
174 for(int i = 0; i < 4; i++) {
175 lcd[i]->draw(60 * i);
179 // ----------------------------------------------------------------------------
181 // ----------------------------------------------------------------------------
183 void VM::initialize_sound(int rate, int samples)
185 // init sound manager
186 event->initialize_sound(rate, samples);
189 pcm->initialize_sound(rate, 8000);
192 uint16_t* VM::create_sound(int* extra_frames)
194 return event->create_sound(extra_frames);
197 int VM::get_sound_buffer_ptr()
199 return event->get_sound_buffer_ptr();
202 #ifdef USE_SOUND_VOLUME
203 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
206 pcm->set_volume(0, decibel_l, decibel_r);
208 drec->set_volume(0, decibel_l, decibel_r);
210 #if defined(USE_SOUND_FILES)
212 for(int i = 0; i < DATAREC_SNDFILE_END; i++) {
213 drec->set_volume(i + 2, decibel_l, decibel_r);
220 // ----------------------------------------------------------------------------
222 // ----------------------------------------------------------------------------
224 void VM::play_tape(const _TCHAR* file_path)
226 drec->play_tape(file_path);
227 drec->write_signal(SIG_DATAREC_REMOTE, 1, 1);
230 void VM::rec_tape(const _TCHAR* file_path)
232 drec->rec_tape(file_path);
233 drec->write_signal(SIG_DATAREC_REMOTE, 1, 1);
236 void VM::close_tape()
238 #if defined(USE_SOUND_FILES)
239 drec->write_signal(SIG_SOUNDER_ADD + DATAREC_SNDFILE_EJECT, 1, 1);
244 drec->write_signal(SIG_DATAREC_REMOTE, 0, 0);
247 bool VM::is_tape_inserted()
249 return drec->is_tape_inserted();
252 bool VM::is_tape_playing()
254 return drec->is_tape_playing();
257 bool VM::is_tape_recording()
259 return drec->is_tape_recording();
262 int VM::get_tape_position()
264 return drec->get_tape_position();
267 bool VM::is_frame_skippable()
269 return event->is_frame_skippable();
272 void VM::update_config()
274 for(DEVICE* device = first_device; device; device = device->next_device) {
275 device->update_config();
279 #define STATE_VERSION 1
281 void VM::save_state(FILEIO* state_fio)
283 state_fio->FputUint32(STATE_VERSION);
285 for(DEVICE* device = first_device; device; device = device->next_device) {
286 device->save_state(state_fio);
288 state_fio->Fwrite(ram, sizeof(ram), 1);
291 bool VM::load_state(FILEIO* state_fio)
293 if(state_fio->FgetUint32() != STATE_VERSION) {
296 for(DEVICE* device = first_device; device; device = device->next_device) {
297 if(!device->load_state(state_fio)) {
301 state_fio->Fread(ram, sizeof(ram), 1);