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 / m5 / m5.cpp
1 /*\r
2         SORD m5 Emulator 'Emu5'\r
3 \r
4         Author : Takeda.Toshiya\r
5         Date   : 2006.08.18 -\r
6 \r
7         [ virtual machine ]\r
8 */\r
9 \r
10 #include "m5.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 "../io.h"\r
17 #include "../memory.h"\r
18 #include "../sn76489an.h"\r
19 #include "../tms9918a.h"\r
20 #include "../z80.h"\r
21 #include "../z80ctc.h"\r
22 \r
23 #ifdef USE_DEBUGGER\r
24 #include "../debugger.h"\r
25 #endif\r
26 \r
27 #include "cmt.h"\r
28 #include "keyboard.h"\r
29 \r
30 // ----------------------------------------------------------------------------\r
31 // initialize\r
32 // ----------------------------------------------------------------------------\r
33 \r
34 VM::VM(EMU* parent_emu) : emu(parent_emu)\r
35 {\r
36         // create devices\r
37         first_device = last_device = NULL;\r
38         dummy = new DEVICE(this, emu);  // must be 1st device\r
39         event = new EVENT(this, emu);   // must be 2nd device\r
40         \r
41         drec = new DATAREC(this, emu);\r
42         io = new IO(this, emu);\r
43         memory = new MEMORY(this, emu);\r
44         psg = new SN76489AN(this, emu);\r
45         vdp = new TMS9918A(this, emu);\r
46         cpu = new Z80(this, emu);\r
47         ctc = new Z80CTC(this, emu);\r
48         \r
49         cmt = new CMT(this, emu);\r
50         key = new KEYBOARD(this, emu);\r
51         \r
52         // set contexts\r
53         event->set_context_cpu(cpu);\r
54         event->set_context_sound(psg);\r
55         \r
56         drec->set_context_out(cmt, SIG_CMT_IN, 1);\r
57         drec->set_context_end(cmt, SIG_CMT_EOT, 1);\r
58         vdp->set_context_irq(ctc, SIG_Z80CTC_TRIG_3, 1);\r
59         cmt->set_context_drec(drec);\r
60         \r
61         // cpu bus\r
62         cpu->set_context_mem(memory);\r
63         cpu->set_context_io(io);\r
64         cpu->set_context_intr(ctc);\r
65 #ifdef USE_DEBUGGER\r
66         cpu->set_context_debugger(new DEBUGGER(this, emu));\r
67 #endif\r
68         \r
69         // z80 family daisy chain\r
70         ctc->set_context_intr(cpu, 0);\r
71         \r
72         // memory bus\r
73         memset(ram, 0, sizeof(ram));\r
74         memset(ext, 0, sizeof(ext));\r
75         memset(ipl, 0xff, sizeof(ipl));\r
76         memset(cart, 0xff, sizeof(cart));\r
77         \r
78         memory->read_bios(_T("IPL.ROM"), ipl, sizeof(ipl));\r
79         \r
80         memory->set_memory_r(0x0000, 0x1fff, ipl);\r
81         memory->set_memory_r(0x2000, 0x6fff, cart);\r
82         memory->set_memory_rw(0x7000, 0x7fff, ram);\r
83         memory->set_memory_rw(0x8000, 0xffff, ext);\r
84         \r
85         // i/o bus\r
86         io->set_iomap_range_rw(0x00, 0x03, ctc);\r
87         io->set_iomap_range_rw(0x10, 0x11, vdp);\r
88         io->set_iomap_single_w(0x20, psg);\r
89         io->set_iomap_range_r(0x30, 0x37, key);\r
90         io->set_iomap_single_w(0x40, cmt);\r
91         io->set_iomap_single_rw(0x50, cmt);\r
92         \r
93         // FD5 floppy drive uint\r
94         subcpu = NULL;\r
95 #ifdef USE_DEBUGGER\r
96 //      subcpu->set_context_debugger(new DEBUGGER(this, emu));\r
97 #endif\r
98         \r
99         // initialize all devices\r
100         for(DEVICE* device = first_device; device; device = device->next_device) {\r
101                 device->initialize();\r
102         }\r
103         inserted = false;\r
104 }\r
105 \r
106 VM::~VM()\r
107 {\r
108         // delete all devices\r
109         for(DEVICE* device = first_device; device;) {\r
110                 DEVICE *next_device = device->next_device;\r
111                 device->release();\r
112                 delete device;\r
113                 device = next_device;\r
114         }\r
115 }\r
116 \r
117 DEVICE* VM::get_device(int id)\r
118 {\r
119         for(DEVICE* device = first_device; device; device = device->next_device) {\r
120                 if(device->this_device_id == id) {\r
121                         return device;\r
122                 }\r
123         }\r
124         return NULL;\r
125 }\r
126 \r
127 // ----------------------------------------------------------------------------\r
128 // drive virtual machine\r
129 // ----------------------------------------------------------------------------\r
130 \r
131 void VM::reset()\r
132 {\r
133         // reset all devices\r
134         for(DEVICE* device = first_device; device; device = device->next_device) {\r
135                 device->reset();\r
136         }\r
137 }\r
138 \r
139 void VM::run()\r
140 {\r
141         event->drive();\r
142 }\r
143 \r
144 // ----------------------------------------------------------------------------\r
145 // debugger\r
146 // ----------------------------------------------------------------------------\r
147 \r
148 #ifdef USE_DEBUGGER\r
149 DEVICE *VM::get_cpu(int index)\r
150 {\r
151         if(index == 0) {\r
152                 return cpu;\r
153         } else if(index == 1) {\r
154                 return subcpu;\r
155         }\r
156         return NULL;\r
157 }\r
158 #endif\r
159 \r
160 // ----------------------------------------------------------------------------\r
161 // draw screen\r
162 // ----------------------------------------------------------------------------\r
163 \r
164 void VM::draw_screen()\r
165 {\r
166         vdp->draw_screen();\r
167 }\r
168 \r
169 // ----------------------------------------------------------------------------\r
170 // soud manager\r
171 // ----------------------------------------------------------------------------\r
172 \r
173 void VM::initialize_sound(int rate, int samples)\r
174 {\r
175         // init sound manager\r
176         event->initialize_sound(rate, samples);\r
177         \r
178         // init sound gen\r
179         psg->init(rate, 3579545, 8000);\r
180 }\r
181 \r
182 uint16* VM::create_sound(int* extra_frames)\r
183 {\r
184         return event->create_sound(extra_frames);\r
185 }\r
186 \r
187 int VM::sound_buffer_ptr()\r
188 {\r
189         return event->sound_buffer_ptr();\r
190 }\r
191 \r
192 // ----------------------------------------------------------------------------\r
193 // user interface\r
194 // ----------------------------------------------------------------------------\r
195 \r
196 void VM::open_cart(int drv, _TCHAR* file_path)\r
197 {\r
198         if(drv == 0) {\r
199                 memset(cart, 0xff, sizeof(cart));\r
200                 inserted = memory->read_image(file_path, cart, sizeof(cart));\r
201                 reset();\r
202         }\r
203 }\r
204 \r
205 void VM::close_cart(int drv)\r
206 {\r
207         if(drv == 0) {\r
208                 memset(cart, 0xff, sizeof(cart));\r
209                 inserted = false;\r
210                 reset();\r
211         }\r
212 }\r
213 \r
214 bool VM::cart_inserted(int drv)\r
215 {\r
216         if(drv == 0) {\r
217                 return inserted;\r
218         } else {\r
219                 return false;\r
220         }\r
221 }\r
222 \r
223 void VM::play_tape(_TCHAR* file_path)\r
224 {\r
225         drec->play_tape(file_path);\r
226 }\r
227 \r
228 void VM::rec_tape(_TCHAR* file_path)\r
229 {\r
230         drec->rec_tape(file_path);\r
231 }\r
232 \r
233 void VM::close_tape()\r
234 {\r
235         drec->close_tape();\r
236 }\r
237 \r
238 bool VM::tape_inserted()\r
239 {\r
240         return drec->tape_inserted();\r
241 }\r
242 \r
243 bool VM::now_skip()\r
244 {\r
245         return event->now_skip();\r
246 }\r
247 \r
248 void VM::update_config()\r
249 {\r
250         for(DEVICE* device = first_device; device; device = device->next_device) {\r
251                 device->update_config();\r
252         }\r
253 }\r
254 \r