OSDN Git Service

[INITIAL] Import 20141226 version of http://homepage3.nifty.com/takeda-toshiya/common...
[csp-qt/common_source_project-fm7.git] / source / src / vm / mycomz80a / mycomz80a.cpp
1 /*\r
2         Japan Electronics College MYCOMZ-80A Emulator 'eMYCOMZ-80A'\r
3 \r
4         Author : Takeda.Toshiya\r
5         Date   : 2009.05.13-\r
6 \r
7         [ virtual machine ]\r
8 */\r
9 \r
10 #include "mycomz80a.h"\r
11 #include "../../emu.h"\r
12 #include "../device.h"\r
13 #include "../event.h"\r
14 \r
15 #include "../datarec.h"\r
16 #include "../hd46505.h"\r
17 #include "../i8255.h"\r
18 #include "../io.h"\r
19 #include "../msm58321.h"\r
20 #include "../sn76489an.h"\r
21 #include "../z80.h"\r
22 \r
23 #ifdef USE_DEBUGGER\r
24 #include "../debugger.h"\r
25 #endif\r
26 \r
27 #include "display.h"\r
28 #include "keyboard.h"\r
29 #include "memory.h"\r
30 \r
31 // ----------------------------------------------------------------------------\r
32 // initialize\r
33 // ----------------------------------------------------------------------------\r
34 \r
35 VM::VM(EMU* parent_emu) : emu(parent_emu)\r
36 {\r
37         // create devices\r
38         first_device = last_device = NULL;\r
39         dummy = new DEVICE(this, emu);  // must be 1st device\r
40         event = new EVENT(this, emu);   // must be 2nd device\r
41         \r
42         drec = new DATAREC(this, emu);\r
43         crtc = new HD46505(this, emu);\r
44         pio1 = new I8255(this, emu);\r
45         pio2 = new I8255(this, emu);\r
46         pio3 = new I8255(this, emu);\r
47         io = new IO(this, emu);\r
48         rtc = new MSM58321(this, emu);  // MSM5832\r
49         psg = new SN76489AN(this, emu);\r
50         cpu = new Z80(this, emu);\r
51         \r
52         display = new DISPLAY(this, emu);\r
53         keyboard = new KEYBOARD(this, emu);\r
54         memory = new MEMORY(this, emu);\r
55         \r
56         // set contexts\r
57         event->set_context_cpu(cpu);\r
58         event->set_context_sound(psg);\r
59         \r
60         //      00      out     system control\r
61         //      01      in/out  vram data\r
62         //      02      out     crtc addr\r
63         //      03      in/out  crtc data\r
64         //      04-07   in/ou   pio1\r
65         //              pa0-7   out     vram addr low, psg data\r
66         //              pb0-7   in      keyboard data\r
67         //              pc0-2   out     vram addr high\r
68         //              pc3     out     fdc format write\r
69         //              pc4     in      keyboard s2\r
70         //              pc5     in      keyboard s3\r
71         //              pc6     in      keyboard s4 (motor on/off)\r
72         //              pc7     in      keyboard s5 (slow)\r
73         //      08-0b   in/ou   pio2\r
74         //              pa0     in      keyboard strobe (1=pressed)\r
75         //              pa1     in      keyboard shift (1=pressed)\r
76         //              pa2     in      cmt in\r
77         //              pa3-6   in      printer ctrl\r
78         //              pa7     in      crtc disptmg\r
79         //              pb0-7   out     printer data\r
80         //              pc0     out     printer strobe\r
81         //              pc1     out     printer reset\r
82         //              pc2     out     cmt out\r
83         //              pc3     out     cmt remote\r
84         //              pc4     out     psg we\r
85         //              pc5     out     psg cs\r
86         //              pc6     out     display chr/cg (0=chr,1=cg)\r
87         //              pc7     out     display freq (0=80column,1=40column)\r
88         //      0c-0f   in/ou   pio3\r
89         //              pa0-6   in      fdc control\r
90         //              pb0-3   in/out  rtc data\r
91         //              pc0-3   out     rtc address\r
92         //              pc4     out     rtc hold\r
93         //              pc5     out     rtc rd\r
94         //              pc6     out     rtc wr\r
95         //              pc7     out     rtc cs\r
96         drec->set_context_out(pio2, SIG_I8255_PORT_A, 4);\r
97         crtc->set_context_disp(pio2, SIG_I8255_PORT_A, 0x80);\r
98         pio1->set_context_port_a(display, SIG_DISPLAY_ADDR_L, 0xff, 0);\r
99         pio1->set_context_port_a(psg, SIG_SN76489AN_DATA, 0xff, 0);\r
100         pio1->set_context_port_c(display, SIG_DISPLAY_ADDR_H, 7, 0);\r
101         pio2->set_context_port_c(drec, SIG_DATAREC_OUT, 4, 0);\r
102         pio2->set_context_port_c(drec, SIG_DATAREC_REMOTE, 8, 0);\r
103         pio2->set_context_port_c(psg, SIG_SN76489AN_WE, 0x10, 0);\r
104         pio2->set_context_port_c(psg, SIG_SN76489AN_CS, 0x20, 0);\r
105         pio2->set_context_port_c(display, SIG_DISPLAY_MODE, 0xc0, 0);\r
106         pio3->set_context_port_b(rtc, SIG_MSM58321_DATA, 0x0f, 0);\r
107         pio3->set_context_port_c(rtc, SIG_MSM5832_ADDR, 0x0f, 0);\r
108         pio3->set_context_port_c(rtc, SIG_MSM5832_HOLD, 0x10, 0);\r
109         pio3->set_context_port_c(rtc, SIG_MSM58321_READ, 0x20, 0);\r
110         pio3->set_context_port_c(rtc, SIG_MSM58321_WRITE, 0x40, 0);\r
111         pio3->set_context_port_c(rtc, SIG_MSM58321_CS, 0x80, 0);\r
112         rtc->set_context_data(pio3, SIG_I8255_PORT_B, 0x0f, 0);\r
113         \r
114         display->set_regs_ptr(crtc->get_regs());\r
115         keyboard->set_context_cpu(cpu);\r
116         keyboard->set_context_pio1(pio1);\r
117         keyboard->set_context_pio2(pio2);\r
118         \r
119         // cpu bus\r
120         cpu->set_context_mem(memory);\r
121         cpu->set_context_io(io);\r
122         cpu->set_context_intr(dummy);\r
123 #ifdef USE_DEBUGGER\r
124         cpu->set_context_debugger(new DEBUGGER(this, emu));\r
125 #endif\r
126         \r
127         // i/o bus\r
128         io->set_iomap_single_w(0x00, memory);\r
129         io->set_iomap_single_rw(0x01, display);\r
130         io->set_iomap_range_rw(0x02, 0x03, crtc);\r
131         io->set_iomap_range_rw(0x04, 0x07, pio1);\r
132         io->set_iomap_range_rw(0x08, 0x0b, pio2);\r
133         io->set_iomap_range_rw(0x0c, 0x0f, pio3);\r
134         \r
135         // initialize all devices\r
136         for(DEVICE* device = first_device; device; device = device->next_device) {\r
137                 device->initialize();\r
138         }\r
139 }\r
140 \r
141 VM::~VM()\r
142 {\r
143         // delete all devices\r
144         for(DEVICE* device = first_device; device;) {\r
145                 DEVICE *next_device = device->next_device;\r
146                 device->release();\r
147                 delete device;\r
148                 device = next_device;\r
149         }\r
150 }\r
151 \r
152 DEVICE* VM::get_device(int id)\r
153 {\r
154         for(DEVICE* device = first_device; device; device = device->next_device) {\r
155                 if(device->this_device_id == id) {\r
156                         return device;\r
157                 }\r
158         }\r
159         return NULL;\r
160 }\r
161 \r
162 // ----------------------------------------------------------------------------\r
163 // drive virtual machine\r
164 // ----------------------------------------------------------------------------\r
165 \r
166 void VM::reset()\r
167 {\r
168         // reset all devices\r
169         for(DEVICE* device = first_device; device; device = device->next_device) {\r
170                 device->reset();\r
171         }\r
172 }\r
173 \r
174 void VM::run()\r
175 {\r
176         event->drive();\r
177 }\r
178 \r
179 double VM::frame_rate()\r
180 {\r
181         return event->frame_rate();\r
182 }\r
183 \r
184 // ----------------------------------------------------------------------------\r
185 // debugger\r
186 // ----------------------------------------------------------------------------\r
187 \r
188 #ifdef USE_DEBUGGER\r
189 DEVICE *VM::get_cpu(int index)\r
190 {\r
191         if(index == 0) {\r
192                 return cpu;\r
193         }\r
194         return NULL;\r
195 }\r
196 #endif\r
197 \r
198 // ----------------------------------------------------------------------------\r
199 // draw screen\r
200 // ----------------------------------------------------------------------------\r
201 \r
202 void VM::draw_screen()\r
203 {\r
204         display->draw_screen();\r
205 }\r
206 \r
207 // ----------------------------------------------------------------------------\r
208 // soud manager\r
209 // ----------------------------------------------------------------------------\r
210 \r
211 void VM::initialize_sound(int rate, int samples)\r
212 {\r
213         // init sound manager\r
214         event->initialize_sound(rate, samples);\r
215         \r
216         // init sound gen\r
217         psg->init(rate, 2500800, 10000);\r
218 }\r
219 \r
220 uint16* VM::create_sound(int* extra_frames)\r
221 {\r
222         return event->create_sound(extra_frames);\r
223 }\r
224 \r
225 int VM::sound_buffer_ptr()\r
226 {\r
227         return event->sound_buffer_ptr();\r
228 }\r
229 \r
230 // ----------------------------------------------------------------------------\r
231 // notify key\r
232 // ----------------------------------------------------------------------------\r
233 \r
234 void VM::key_down(int code, bool repeat)\r
235 {\r
236         keyboard->key_down(code);\r
237 }\r
238 \r
239 void VM::key_up(int code)\r
240 {\r
241         keyboard->key_up(code);\r
242 }\r
243 \r
244 // ----------------------------------------------------------------------------\r
245 // user interface\r
246 // ----------------------------------------------------------------------------\r
247 \r
248 void VM::play_tape(_TCHAR* file_path)\r
249 {\r
250         drec->play_tape(file_path);\r
251 //      drec->write_signal(SIG_DATAREC_REMOTE, 1, 1);\r
252 }\r
253 \r
254 void VM::rec_tape(_TCHAR* file_path)\r
255 {\r
256         drec->rec_tape(file_path);\r
257 //      drec->write_signal(SIG_DATAREC_REMOTE, 1, 1);\r
258 }\r
259 \r
260 void VM::close_tape()\r
261 {\r
262         drec->close_tape();\r
263 //      drec->write_signal(SIG_DATAREC_REMOTE, 0, 1);\r
264 }\r
265 \r
266 bool VM::tape_inserted()\r
267 {\r
268         return drec->tape_inserted();\r
269 }\r
270 \r
271 bool VM::now_skip()\r
272 {\r
273         return event->now_skip();\r
274 }\r
275 \r
276 void VM::update_config()\r
277 {\r
278         for(DEVICE* device = first_device; device; device = device->next_device) {\r
279                 device->update_config();\r
280         }\r
281 }\r
282 \r