OSDN Git Service

[General] Convert sourcecode's CRLF format: DOS(WINDOWS) to Unix, to apply patches...
[csp-qt/common_source_project-fm7.git] / source / src / vm / fp1100 / fp1100.cpp
1 /*
2         CASIO FP-1100 Emulator 'eFP-1100'
3
4         Author : Takeda.Toshiya
5         Date   : 2010.06.18-
6
7         [ virtual machine ]
8 */
9
10 #include "fp1100.h"
11 #include "../../emu.h"
12 #include "../device.h"
13 #include "../event.h"
14
15 #include "../beep.h"
16 #include "../disk.h"
17 #include "../hd46505.h"
18 #include "../upd765a.h"
19 #include "../upd7801.h"
20 #include "../z80.h"
21
22 #ifdef USE_DEBUGGER
23 #include "../debugger.h"
24 #endif
25
26 #include "main.h"
27 #include "sub.h"
28 #include "fdcpack.h"
29 #include "rampack.h"
30 #include "rompack.h"
31
32 #include "../../fileio.h"
33
34 // ----------------------------------------------------------------------------
35 // initialize
36 // ----------------------------------------------------------------------------
37
38 VM::VM(EMU* parent_emu) : emu(parent_emu)
39 {
40         // create devices
41         first_device = last_device = NULL;
42         dummy = new DEVICE(this, emu);  // must be 1st device
43         event = new EVENT(this, emu);   // must be 2nd device
44         
45         beep = new BEEP(this, emu);
46         crtc = new HD46505(this, emu);
47         fdc = new UPD765A(this, emu);
48         subcpu = new UPD7801(this, emu);
49         cpu = new Z80(this, emu);
50         
51         main = new MAIN(this, emu);
52         sub = new SUB(this, emu);
53         fdcpack = new FDCPACK(this, emu);
54         rampack1 = new RAMPACK(this, emu);
55         rampack1->index = 1;
56         rampack2 = new RAMPACK(this, emu);
57         rampack2->index = 2;
58         rampack3 = new RAMPACK(this, emu);
59         rampack3->index = 3;
60         rampack4 = new RAMPACK(this, emu);
61         rampack4->index = 4;
62         rampack5 = new RAMPACK(this, emu);
63         rampack5->index = 5;
64         rampack6 = new RAMPACK(this, emu);
65         rampack6->index = 6;
66         rompack = new ROMPACK(this, emu);
67         
68         // set contexts
69         event->set_context_cpu(cpu);
70         event->set_context_cpu(subcpu, SUB_CPU_CLOCKS);
71         event->set_context_sound(beep);
72         
73         crtc->set_context_hsync(sub, SIG_SUB_HSYNC, 1);
74         fdc->set_context_drq(main, SIG_MAIN_INTA, 1);
75         fdc->set_context_irq(main, SIG_MAIN_INTB, 1);
76         
77         main->set_context_cpu(cpu);
78         main->set_context_sub(sub);
79         main->set_context_slot(0, rampack1);
80         main->set_context_slot(1, rampack2);
81         main->set_context_slot(2, rampack3);
82         main->set_context_slot(3, rampack4);
83         main->set_context_slot(4, rampack5);
84         main->set_context_slot(5, rampack6);
85         main->set_context_slot(6, rompack);
86         main->set_context_slot(7, fdcpack);
87         
88         sub->set_context_cpu(subcpu);
89         sub->set_context_main(main);
90         sub->set_context_beep(beep);
91         sub->set_context_crtc(crtc, crtc->get_regs());
92         
93         fdcpack->set_context_fdc(fdc);
94         
95         // cpu bus
96         cpu->set_context_mem(main);
97         cpu->set_context_io(main);
98         cpu->set_context_intr(main);
99 #ifdef USE_DEBUGGER
100         cpu->set_context_debugger(new DEBUGGER(this, emu));
101 #endif
102         subcpu->set_context_mem(sub);
103         subcpu->set_context_io(sub);
104 #ifdef USE_DEBUGGER
105         subcpu->set_context_debugger(new DEBUGGER(this, emu));
106 #endif
107         
108         // initialize all devices
109         for(DEVICE* device = first_device; device; device = device->next_device) {
110                 device->initialize();
111         }
112         for(int i = 0; i < 4; i++) {
113                 fdc->set_drive_type(i, DRIVE_TYPE_2D);
114         }
115 }
116
117 VM::~VM()
118 {
119         // delete all devices
120         for(DEVICE* device = first_device; device;) {
121                 DEVICE *next_device = device->next_device;
122                 device->release();
123                 delete device;
124                 device = next_device;
125         }
126 }
127
128 DEVICE* VM::get_device(int id)
129 {
130         for(DEVICE* device = first_device; device; device = device->next_device) {
131                 if(device->this_device_id == id) {
132                         return device;
133                 }
134         }
135         return NULL;
136 }
137
138 // ----------------------------------------------------------------------------
139 // drive virtual machine
140 // ----------------------------------------------------------------------------
141
142 void VM::reset()
143 {
144         // reset all devices
145         for(DEVICE* device = first_device; device; device = device->next_device) {
146                 device->reset();
147         }
148 }
149
150 void VM::run()
151 {
152         event->drive();
153 }
154
155 double VM::frame_rate()
156 {
157         return event->frame_rate();
158 }
159
160 // ----------------------------------------------------------------------------
161 // debugger
162 // ----------------------------------------------------------------------------
163
164 #ifdef USE_DEBUGGER
165 DEVICE *VM::get_cpu(int index)
166 {
167         if(index == 0) {
168                 return cpu;
169         } else if(index == 1) {
170                 return subcpu;
171         }
172         return NULL;
173 }
174 #endif
175
176 // ----------------------------------------------------------------------------
177 // draw screen
178 // ----------------------------------------------------------------------------
179
180 void VM::draw_screen()
181 {
182         sub->draw_screen();
183 }
184
185 int VM::access_lamp()
186 {
187         uint32 status = fdc->read_signal(0);
188         return (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0;
189 }
190
191 // ----------------------------------------------------------------------------
192 // soud manager
193 // ----------------------------------------------------------------------------
194
195 void VM::initialize_sound(int rate, int samples)
196 {
197         // init sound manager
198         event->initialize_sound(rate, samples);
199         
200         // init sound gen
201         beep->init(rate, 2400, 8000);
202 }
203
204 uint16* VM::create_sound(int* extra_frames)
205 {
206         return event->create_sound(extra_frames);
207 }
208
209 int VM::sound_buffer_ptr()
210 {
211         return event->sound_buffer_ptr();
212 }
213
214 // ----------------------------------------------------------------------------
215 // notify key
216 // ----------------------------------------------------------------------------
217
218 void VM::key_down(int code, bool repeat)
219 {
220         sub->key_down(code);
221 }
222
223 void VM::key_up(int code)
224 {
225         sub->key_up(code);
226 }
227
228 // ----------------------------------------------------------------------------
229 // user interface
230 // ----------------------------------------------------------------------------
231
232 void VM::open_disk(int drv, _TCHAR* file_path, int offset)
233 {
234         fdc->open_disk(drv, file_path, offset);
235 }
236
237 void VM::close_disk(int drv)
238 {
239         fdc->close_disk(drv);
240 }
241
242 bool VM::disk_inserted(int drv)
243 {
244         return fdc->disk_inserted(drv);
245 }
246
247 void VM::play_tape(_TCHAR* file_path)
248 {
249         sub->play_tape(file_path);
250 }
251
252 void VM::rec_tape(_TCHAR* file_path)
253 {
254         sub->rec_tape(file_path);
255 }
256
257 void VM::close_tape()
258 {
259         sub->close_tape();
260 }
261
262 bool VM::tape_inserted()
263 {
264         return sub->tape_inserted();
265 }
266
267 bool VM::now_skip()
268 {
269         return event->now_skip();
270 }
271
272 void VM::update_config()
273 {
274         for(DEVICE* device = first_device; device; device = device->next_device) {
275                 device->update_config();
276         }
277 }
278
279 #define STATE_VERSION   1
280
281 void VM::save_state(FILEIO* state_fio)
282 {
283         state_fio->FputUint32(STATE_VERSION);
284         
285         for(DEVICE* device = first_device; device; device = device->next_device) {
286                 device->save_state(state_fio);
287         }
288 }
289
290 bool VM::load_state(FILEIO* state_fio)
291 {
292         if(state_fio->FgetUint32() != STATE_VERSION) {
293                 return false;
294         }
295         for(DEVICE* device = first_device; device; device = device->next_device) {
296                 if(!device->load_state(state_fio)) {
297                         return false;
298                 }
299         }
300         return true;
301 }
302