2 TOSHIBA EX-80 Emulator 'eEX-80'
4 Author : Takeda.Toshiya
11 #include "../../emu.h"
12 #include "../device.h"
19 #include "../pcm1bit.h"
22 #include "../debugger.h"
26 #include "./display.h"
27 #include "./keyboard.h"
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu)
42 first_device = last_device = NULL;
43 dummy = new DEVICE(this, emu); // must be 1st device
44 event = new EVENT(this, emu); // must be 2nd device
46 sio = new I8251(this, emu);
47 pio = new I8255(this, emu);
48 io = new IO(this, emu);
49 pcm = new PCM1BIT(this, emu);
51 // pcm->set_context_debugger(new DEBUGGER(this, emu));
53 cpu = new I8080(this, emu);
55 cmt = new CMT(this, emu);
56 display = new DISPLAY(this, emu);
57 keyboard = new KEYBOARD(this, emu);
58 memory = new MEMORY(this, emu);
61 dummy->set_device_name(_T("1st Dummy"));
63 pio->set_device_name(_T("i8255(SOUND/KEY/DISPLAY)"));
64 sio->set_device_name(_T("i8251(CMT)"));
65 pcm->set_device_name(_T("SOUND OUT"));
69 event->set_context_cpu(cpu);
70 event->set_context_sound(pcm);
72 sio->set_context_out(cmt, SIG_CMT_OUT);
73 pio->set_context_port_c(pcm, SIG_PCM1BIT_SIGNAL, 0x08, 0);
74 pio->set_context_port_c(keyboard, SIG_KEYBOARD_COLUMN, 0x70, 0);
75 pio->set_context_port_c(display, SIG_DISPLAY_DMA, 0x80, 0);
76 // Sound:: Force realtime rendering. This is temporally fix. 20161024 K.O
77 //pcm->set_realtime_render(true);
79 cmt->set_context_sio(sio);
80 display->set_context_cpu(cpu);
81 display->set_ram_ptr(memory->get_ram());
82 keyboard->set_context_pio(pio);
83 memory->set_context_cpu(cpu);
86 cpu->set_context_mem(memory);
87 cpu->set_context_io(io);
88 cpu->set_context_intr(dummy);
90 cpu->set_context_debugger(new DEBUGGER(this, emu));
94 io->set_iomap_range_rw(0xdc, 0xdd, sio);
95 io->set_iomap_range_rw(0xf8, 0xfb, pio);
97 // initialize all devices
98 #if defined(__GIT_REPO_VERSION)
99 strncpy(_git_revision, __GIT_REPO_VERSION, sizeof(_git_revision) - 1);
101 for(DEVICE* device = first_device; device; device = device->next_device) {
102 device->initialize();
108 // delete all devices
109 for(DEVICE* device = first_device; device;) {
110 DEVICE *next_device = device->next_device;
113 device = next_device;
117 DEVICE* VM::get_device(int id)
119 for(DEVICE* device = first_device; device; device = device->next_device) {
120 if(device->this_device_id == id) {
127 // ----------------------------------------------------------------------------
128 // drive virtual machine
129 // ----------------------------------------------------------------------------
134 for(DEVICE* device = first_device; device; device = device->next_device) {
144 // ----------------------------------------------------------------------------
146 // ----------------------------------------------------------------------------
149 DEVICE *VM::get_cpu(int index)
158 // ----------------------------------------------------------------------------
160 // ----------------------------------------------------------------------------
162 void VM::draw_screen()
164 display->draw_screen();
167 int VM::max_draw_ranges()
169 return (config.monitor_type == 0) ? 9 : 8;
172 // ----------------------------------------------------------------------------
174 // ----------------------------------------------------------------------------
176 void VM::initialize_sound(int rate, int samples)
178 // init sound manager
179 event->initialize_sound(rate, samples);
182 pcm->initialize_sound(rate, 8000);
185 uint16_t* VM::create_sound(int* extra_frames)
187 return event->create_sound(extra_frames);
190 int VM::get_sound_buffer_ptr()
192 return event->get_sound_buffer_ptr();
195 #ifdef USE_SOUND_VOLUME
196 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
199 pcm->set_volume(0, decibel_l, decibel_r);
204 // ----------------------------------------------------------------------------
206 // ----------------------------------------------------------------------------
208 void VM::load_binary(int drv, const _TCHAR* file_path)
211 memory->load_binary(file_path);
215 void VM::save_binary(int drv, const _TCHAR* file_path)
218 memory->save_binary(file_path);
222 void VM::play_tape(int drv, const _TCHAR* file_path)
224 cmt->play_tape(file_path);
227 void VM::rec_tape(int drv, const _TCHAR* file_path)
229 cmt->rec_tape(file_path);
232 void VM::close_tape(int drv)
237 bool VM::is_tape_inserted(int drv)
239 return cmt->is_tape_inserted();
242 bool VM::is_frame_skippable()
244 return event->is_frame_skippable();
247 void VM::update_config()
249 for(DEVICE* device = first_device; device; device = device->next_device) {
250 device->update_config();
254 double VM::get_current_usec()
256 if(event == NULL) return 0.0;
257 return event->get_current_usec();
260 uint64_t VM::get_current_clock_uint64()
262 if(event == NULL) return (uint64_t)0;
263 return event->get_current_clock_uint64();
266 #define STATE_VERSION 2
268 bool VM::process_state(FILEIO* state_fio, bool loading)
270 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
273 for(DEVICE* device = first_device; device; device = device->next_device) {
274 // Note: typeid(foo).name is fixed by recent ABI.Not dec 6.
275 // const char *name = typeid(*device).name();
276 // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O
277 const char *name = device->get_device_name();
278 int len = (int)strlen(name);
280 if(!state_fio->StateCheckInt32(len)) {
282 printf("Class name len Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name);
286 if(!state_fio->StateCheckBuffer(name, len, 1)) {
288 printf("Class name Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name);
292 if(!device->process_state(state_fio, loading)) {
294 printf("Data loading Error: DEVID=%d\n", device->this_device_id);
299 // Machine specified.