2 Japan Electronics College MYCOMZ-80A Emulator 'eMYCOMZ-80A'
4 Author : Takeda.Toshiya
10 #include "mycomz80a.h"
11 #include "../../emu.h"
12 #include "../device.h"
15 #include "../datarec.h"
16 #include "../hd46505.h"
19 #include "../msm58321.h"
20 #include "../sn76489an.h"
24 #include "../debugger.h"
31 #include "../../fileio.h"
33 // ----------------------------------------------------------------------------
35 // ----------------------------------------------------------------------------
37 VM::VM(EMU* parent_emu) : emu(parent_emu)
40 first_device = last_device = NULL;
41 dummy = new DEVICE(this, emu); // must be 1st device
42 event = new EVENT(this, emu); // must be 2nd device
44 drec = new DATAREC(this, emu);
45 crtc = new HD46505(this, emu);
46 pio1 = new I8255(this, emu);
47 pio2 = new I8255(this, emu);
48 pio3 = new I8255(this, emu);
49 io = new IO(this, emu);
50 rtc = new MSM58321(this, emu); // MSM5832
51 psg = new SN76489AN(this, emu);
52 cpu = new Z80(this, emu);
54 display = new DISPLAY(this, emu);
55 keyboard = new KEYBOARD(this, emu);
56 memory = new MEMORY(this, emu);
59 event->set_context_cpu(cpu);
60 event->set_context_sound(psg);
62 // 00 out system control
63 // 01 in/out vram data
65 // 03 in/out crtc data
67 // pa0-7 out vram addr low, psg data
68 // pb0-7 in keyboard data
69 // pc0-2 out vram addr high
70 // pc3 out fdc format write
73 // pc6 in keyboard s4 (motor on/off)
74 // pc7 in keyboard s5 (slow)
76 // pa0 in keyboard strobe (1=pressed)
77 // pa1 in keyboard shift (1=pressed)
79 // pa3-6 in printer ctrl
80 // pa7 in crtc disptmg
81 // pb0-7 out printer data
82 // pc0 out printer strobe
83 // pc1 out printer reset
88 // pc6 out display chr/cg (0=chr,1=cg)
89 // pc7 out display freq (0=80column,1=40column)
91 // pa0-6 in fdc control
92 // pb0-3 in/out rtc data
93 // pc0-3 out rtc address
98 drec->set_context_out(pio2, SIG_I8255_PORT_A, 4);
99 crtc->set_context_disp(pio2, SIG_I8255_PORT_A, 0x80);
100 pio1->set_context_port_a(display, SIG_DISPLAY_ADDR_L, 0xff, 0);
101 pio1->set_context_port_a(psg, SIG_SN76489AN_DATA, 0xff, 0);
102 pio1->set_context_port_c(display, SIG_DISPLAY_ADDR_H, 7, 0);
103 pio2->set_context_port_c(drec, SIG_DATAREC_OUT, 4, 0);
104 pio2->set_context_port_c(drec, SIG_DATAREC_REMOTE, 8, 0);
105 pio2->set_context_port_c(psg, SIG_SN76489AN_WE, 0x10, 0);
106 pio2->set_context_port_c(psg, SIG_SN76489AN_CS, 0x20, 0);
107 pio2->set_context_port_c(display, SIG_DISPLAY_MODE, 0xc0, 0);
108 pio3->set_context_port_b(rtc, SIG_MSM58321_DATA, 0x0f, 0);
109 pio3->set_context_port_c(rtc, SIG_MSM5832_ADDR, 0x0f, 0);
110 pio3->set_context_port_c(rtc, SIG_MSM5832_HOLD, 0x10, 0);
111 pio3->set_context_port_c(rtc, SIG_MSM58321_READ, 0x20, 0);
112 pio3->set_context_port_c(rtc, SIG_MSM58321_WRITE, 0x40, 0);
113 pio3->set_context_port_c(rtc, SIG_MSM58321_CS, 0x80, 0);
114 rtc->set_context_data(pio3, SIG_I8255_PORT_B, 0x0f, 0);
116 display->set_regs_ptr(crtc->get_regs());
117 keyboard->set_context_cpu(cpu);
118 keyboard->set_context_pio1(pio1);
119 keyboard->set_context_pio2(pio2);
122 cpu->set_context_mem(memory);
123 cpu->set_context_io(io);
124 cpu->set_context_intr(dummy);
126 cpu->set_context_debugger(new DEBUGGER(this, emu));
130 io->set_iomap_single_w(0x00, memory);
131 io->set_iomap_single_rw(0x01, display);
132 io->set_iomap_range_rw(0x02, 0x03, crtc);
133 io->set_iomap_range_rw(0x04, 0x07, pio1);
134 io->set_iomap_range_rw(0x08, 0x0b, pio2);
135 io->set_iomap_range_rw(0x0c, 0x0f, pio3);
137 // initialize all devices
138 for(DEVICE* device = first_device; device; device = device->next_device) {
139 device->initialize();
145 // delete all devices
146 for(DEVICE* device = first_device; device;) {
147 DEVICE *next_device = device->next_device;
150 device = next_device;
154 DEVICE* VM::get_device(int id)
156 for(DEVICE* device = first_device; device; device = device->next_device) {
157 if(device->this_device_id == id) {
164 // ----------------------------------------------------------------------------
165 // drive virtual machine
166 // ----------------------------------------------------------------------------
171 for(DEVICE* device = first_device; device; device = device->next_device) {
181 double VM::frame_rate()
183 return event->frame_rate();
186 // ----------------------------------------------------------------------------
188 // ----------------------------------------------------------------------------
191 DEVICE *VM::get_cpu(int index)
200 // ----------------------------------------------------------------------------
202 // ----------------------------------------------------------------------------
204 void VM::draw_screen()
206 display->draw_screen();
209 // ----------------------------------------------------------------------------
211 // ----------------------------------------------------------------------------
213 void VM::initialize_sound(int rate, int samples)
215 // init sound manager
216 event->initialize_sound(rate, samples);
219 psg->init(rate, 2500800, 10000);
222 uint16* VM::create_sound(int* extra_frames)
224 return event->create_sound(extra_frames);
227 int VM::sound_buffer_ptr()
229 return event->sound_buffer_ptr();
232 // ----------------------------------------------------------------------------
234 // ----------------------------------------------------------------------------
236 void VM::key_down(int code, bool repeat)
238 keyboard->key_down(code);
241 void VM::key_up(int code)
243 keyboard->key_up(code);
246 // ----------------------------------------------------------------------------
248 // ----------------------------------------------------------------------------
250 void VM::play_tape(_TCHAR* file_path)
252 drec->play_tape(file_path);
253 // drec->write_signal(SIG_DATAREC_REMOTE, 1, 1);
256 void VM::rec_tape(_TCHAR* file_path)
258 drec->rec_tape(file_path);
259 // drec->write_signal(SIG_DATAREC_REMOTE, 1, 1);
262 void VM::close_tape()
265 // drec->write_signal(SIG_DATAREC_REMOTE, 0, 1);
268 bool VM::tape_inserted()
270 return drec->tape_inserted();
275 return event->now_skip();
278 void VM::update_config()
280 for(DEVICE* device = first_device; device; device = device->next_device) {
281 device->update_config();
285 #define STATE_VERSION 1
287 void VM::save_state(FILEIO* state_fio)
289 state_fio->FputUint32(STATE_VERSION);
291 for(DEVICE* device = first_device; device; device = device->next_device) {
292 device->save_state(state_fio);
296 bool VM::load_state(FILEIO* state_fio)
298 if(state_fio->FgetUint32() != STATE_VERSION) {
301 for(DEVICE* device = first_device; device; device = device->next_device) {
302 if(!device->load_state(state_fio)) {