2 EPSON HC-20 Emulator 'eHC-20'
4 Author : Takeda.Toshiya
11 #include "../../emu.h"
12 #include "../device.h"
17 #include "../hd146818p.h"
19 //#include "../mc6800.h"
20 #include "../hd6301.h"
23 #include "../upd765a.h"
25 #include "../z80sio.h"
28 #include "../debugger.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
45 dummy->set_device_name(_T("1st Dummy"));
47 beep = new BEEP(this, emu);
48 rtc = new HD146818P(this, emu);
49 //cpu = new MC6800(this, emu);
50 cpu = new HD6301(this, emu);
51 tf20 = new TF20(this, emu);
52 pio_tf20 = new I8255(this, emu);
53 fdc_tf20 = new UPD765A(this, emu);
54 fdc_tf20->set_context_noise_seek(new NOISE(this, emu));
55 fdc_tf20->set_context_noise_head_down(new NOISE(this, emu));
56 fdc_tf20->set_context_noise_head_up(new NOISE(this, emu));
57 cpu_tf20 = new Z80(this, emu);
58 sio_tf20 = new Z80SIO(this, emu);
59 pio_tf20->set_device_name(_T("TF20 PIO(i8255)"));
60 cpu_tf20->set_device_name(_T("TF20 CPU(Z80)"));
61 sio_tf20->set_device_name(_T("TF20 SIO(Z80 SIO)"));
62 fdc_tf20->set_device_name(_T("TF20 FDC(uPD765A)"));
63 memory = new MEMORY(this, emu);
65 event->set_context_cpu(cpu);
66 event->set_context_cpu(cpu_tf20, 4000000);
67 event->set_context_sound(beep);
68 event->set_context_sound(fdc_tf20->get_context_noise_seek());
69 event->set_context_sound(fdc_tf20->get_context_noise_head_down());
70 event->set_context_sound(fdc_tf20->get_context_noise_head_up());
74 0002 in --- port1 (cpu)
75 0003 in/out --- port2 (cpu)
78 0020 out bit0-7 key scan line
79 0022 in bit0-7 key scan result (lo)
80 0026 out bit0-2 selection of lcd driver (0,1-6)
81 bit3 output selection for lcd driver (0=data 1=command)
82 bit4 key input interrupt mask (0=Mask)
83 bit5 pout (serial control line)
84 bit6 shift/load select for rom cartridge (0=load 1=shift)
85 bit7 clock for rom cartridge
86 0028 in bit0-1 key scan result (hi)
87 bit6 power switch interrupt flag (0=active)
88 bit7 busy signal of lcd controller (0=busy)
89 002a out bit0-7 output data to lcd controller
90 in --- serial clock to lcd controller
91 002b in --- serial clock to lcd controller
92 002c in/out --- used for interrupt mask setting in sleep mode
93 0030 in/out --- select expansion unit rom (bank1)
94 0032 in/out --- select internal rom (bank0)
95 0033 in/out --- select internal rom (bank0)
96 003c in --- XXX: unknown
101 p12 in error status of slave mcu (P34)
102 p13 in external interrupt flag(0=active)
103 p14 in battery voltage interrupt flag (0=active)
104 p15 in key input inerrupt flag (0=active)
105 p16 in pin (serial control line)
106 p17 in counter status of microcassete / rom data / plug-in option
109 p20 in barcode input signal (1=mark 0=space)
110 p21 out txd (RS-232C)
111 p22 out selection for CPU serial communication (0=slave 1=serial)
113 cpu->set_context_port2(memory, SIG_MEMORY_PORT_2, 0xff, 0);
114 cpu->set_context_port3(memory, SIG_MEMORY_PORT_3, 0xff, 0);
115 cpu->set_context_port4(memory, SIG_MEMORY_PORT_4, 0xff, 0);
116 cpu->set_context_sio(memory, SIG_MEMORY_SIO_MAIN);
117 rtc->set_context_intr_line(memory, SIG_MEMORY_RTC_IRQ, 1);
119 memory->set_context_beep(beep);
120 memory->set_context_cpu(cpu);
121 memory->set_context_rtc(rtc);
122 memory->set_context_sio_tf20(sio_tf20);
125 cpu->set_context_mem(memory);
127 cpu->set_context_debugger(new DEBUGGER(this, emu));
131 tf20->set_context_cpu(cpu_tf20);
132 tf20->set_context_fdc(fdc_tf20);
133 tf20->set_context_pio(pio_tf20);
134 tf20->set_context_sio(sio_tf20);
135 cpu_tf20->set_context_mem(tf20);
136 cpu_tf20->set_context_io(tf20);
137 cpu_tf20->set_context_intr(tf20);
139 cpu_tf20->set_context_debugger(new DEBUGGER(this, emu));
140 // beep->set_context_debugger(new DEBUGGER(this, emu));
141 // fdc_tf20->set_context_debugger(new DEBUGGER(this, emu));
144 fdc_tf20->set_context_irq(cpu_tf20, SIG_CPU_IRQ, 1);
145 sio_tf20->set_context_send(0, memory, SIG_MEMORY_SIO_TF20);
146 sio_tf20->set_tx_clock(0, 4915200 / 8); // 4.9152MHz / 8 (38.4kbps)
147 sio_tf20->set_rx_clock(0, 4915200 / 8); // baud-rate can be changed by jumper pin
148 sio_tf20->set_tx_clock(1, 4915200 / 8);
149 sio_tf20->set_rx_clock(1, 4915200 / 8);
151 // initialize all devices
152 #if defined(__GIT_REPO_VERSION)
153 set_git_repo_version(__GIT_REPO_VERSION);
155 initialize_devices();
157 for(int i = 0; i < MAX_DRIVE; i++) {
158 fdc_tf20->set_drive_type(i, DRIVE_TYPE_2D);
164 // delete all devices
165 for(DEVICE* device = first_device; device;) {
166 DEVICE *next_device = device->next_device;
169 device = next_device;
174 // ----------------------------------------------------------------------------
175 // drive virtual machine
176 // ----------------------------------------------------------------------------
181 VM_TEMPLATE::reset();
182 cpu->write_signal(SIG_MC6801_PORT_1, 0x78, 0xff);
183 cpu->write_signal(SIG_MC6801_PORT_2, 0x9e, 0xff);
186 void VM::notify_power_off()
188 // this->out_debug_log(T("--- POWER OFF ---\n"));
189 memory->notify_power_off();
197 // ----------------------------------------------------------------------------
199 // ----------------------------------------------------------------------------
202 DEVICE *VM::get_cpu(int index)
206 } else if(index == 1) {
213 // ----------------------------------------------------------------------------
215 // ----------------------------------------------------------------------------
217 void VM::draw_screen()
219 memory->draw_screen();
222 // ----------------------------------------------------------------------------
224 // ----------------------------------------------------------------------------
226 void VM::initialize_sound(int rate, int samples)
228 // init sound manager
229 event->initialize_sound(rate, samples);
232 beep->initialize_sound(rate, 1000, 8000);
235 uint16_t* VM::create_sound(int* extra_frames)
237 return event->create_sound(extra_frames);
240 int VM::get_sound_buffer_ptr()
242 return event->get_sound_buffer_ptr();
245 #ifdef USE_SOUND_VOLUME
246 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
249 beep->set_volume(0, decibel_l, decibel_r);
251 fdc_tf20->get_context_noise_seek()->set_volume(0, decibel_l, decibel_r);
252 fdc_tf20->get_context_noise_head_down()->set_volume(0, decibel_l, decibel_r);
253 fdc_tf20->get_context_noise_head_up()->set_volume(0, decibel_l, decibel_r);
258 // ----------------------------------------------------------------------------
260 // ----------------------------------------------------------------------------
262 void VM::key_down(int code, bool repeat)
264 memory->key_down(code);
267 void VM::key_up(int code)
269 memory->key_up(code);
272 // ----------------------------------------------------------------------------
274 // ----------------------------------------------------------------------------
276 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
278 fdc_tf20->open_disk(drv, file_path, bank);
281 void VM::close_floppy_disk(int drv)
283 fdc_tf20->close_disk(drv);
286 bool VM::is_floppy_disk_inserted(int drv)
288 return fdc_tf20->is_disk_inserted(drv);
291 void VM::is_floppy_disk_protected(int drv, bool value)
293 fdc_tf20->is_disk_protected(drv, value);
296 bool VM::is_floppy_disk_protected(int drv)
298 return fdc_tf20->is_disk_protected(drv);
301 uint32_t VM::is_floppy_disk_accessed()
303 return fdc_tf20->read_signal(0);
306 void VM::play_tape(int drv, const _TCHAR* file_path)
308 memory->play_tape(file_path);
311 void VM::rec_tape(int drv, const _TCHAR* file_path)
313 memory->rec_tape(file_path);
316 void VM::close_tape(int drv)
318 memory->close_tape();
321 bool VM::is_tape_inserted(int drv)
323 return memory->is_tape_inserted();
326 bool VM::is_frame_skippable()
328 return event->is_frame_skippable();
332 double VM::get_current_usec()
334 __UNLIKELY_IF(event == NULL) return 0.0;
335 return event->get_current_usec();
338 uint64_t VM::get_current_clock_uint64()
340 __UNLIKELY_IF(event == NULL) return (uint64_t)0;
341 return event->get_current_clock_uint64();
344 #define STATE_VERSION 3
346 bool VM::process_state(FILEIO* state_fio, bool loading)
348 if(!(VM_TEMPLATE::process_state_core(state_fio, loading, STATE_VERSION))) {