OSDN Git Service

[VM][General][WIP] Apply new (Upstream 2016-02-21) APIs to VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fp200 / fp200.cpp
1 /*
2         CASIO FP-200 Emulator 'eFP-200'
3
4         Author : Takeda.Toshiya
5         Date   : 2013.03.21-
6
7         [ virtual machine ]
8 */
9
10 #include "fp200.h"
11 #include "../../emu.h"
12 #include "../device.h"
13 #include "../event.h"
14
15 #include "../datarec.h"
16 #include "../i8080.h"
17 #include "../memory.h"
18 #include "../rp5c01.h"
19
20 #ifdef USE_DEBUGGER
21 #include "../debugger.h"
22 #endif
23
24 #include "io.h"
25
26 // ----------------------------------------------------------------------------
27 // initialize
28 // ----------------------------------------------------------------------------
29
30 VM::VM(EMU* parent_emu) : emu(parent_emu)
31 {
32         // create devices
33         first_device = last_device = NULL;
34         dummy = new DEVICE(this, emu);  // must be 1st device
35         event = new EVENT(this, emu);   // must be 2nd device
36         
37         drec = new DATAREC(this, emu);
38         cpu = new I8080(this, emu);     // i8085
39         memory = new MEMORY(this, emu);
40         rtc = new RP5C01(this, emu);
41         
42         io = new IO(this, emu);
43         
44         // set contexts
45         event->set_context_cpu(cpu);
46         event->set_context_sound(drec);
47         
48         drec->set_context_ear(io, SIG_IO_CMT, 1);
49         cpu->set_context_sod(io, SIG_IO_SOD, 1);
50         
51         io->set_context_cpu(cpu);
52         io->set_context_drec(drec);
53         io->set_context_rtc(rtc);
54         
55         // cpu bus
56         cpu->set_context_mem(memory);
57         cpu->set_context_io(io);
58         cpu->set_context_intr(io);
59 #ifdef USE_DEBUGGER
60         cpu->set_context_debugger(new DEBUGGER(this, emu));
61 #endif
62         
63         // memory bus
64         memset(rom, 0xff, sizeof(rom));
65         memset(ram, 0, sizeof(ram));
66         
67         memory->read_bios(_T("BIOS.ROM"), rom, sizeof(rom));
68         
69         FILEIO* fio = new FILEIO();
70         if(fio->Fopen(create_local_path(_T("RAM.BIN")), FILEIO_READ_BINARY)) {
71                 fio->Fread(ram, sizeof(ram), 1);
72                 fio->Fclose();
73         }
74         delete fio;
75         
76         memory->set_memory_r(0x0000, 0x7fff, rom);
77         memory->set_memory_rw(0x8000, 0xffff, ram);
78         memory->set_wait_rw(0x0000, 0xffff, 1);
79         
80         // initialize all devices
81         for(DEVICE* device = first_device; device; device = device->next_device) {
82                 device->initialize();
83         }
84 }
85
86 VM::~VM()
87 {
88         FILEIO* fio = new FILEIO();
89         if(fio->Fopen(create_local_path(_T("RAM.BIN")), FILEIO_WRITE_BINARY)) {
90                 fio->Fwrite(ram, sizeof(ram), 1);
91                 fio->Fclose();
92         }
93         delete fio;
94         
95         // delete all devices
96         for(DEVICE* device = first_device; device;) {
97                 DEVICE *next_device = device->next_device;
98                 device->release();
99                 delete device;
100                 device = next_device;
101         }
102 }
103
104 DEVICE* VM::get_device(int id)
105 {
106         for(DEVICE* device = first_device; device; device = device->next_device) {
107                 if(device->this_device_id == id) {
108                         return device;
109                 }
110         }
111         return NULL;
112 }
113
114 // ----------------------------------------------------------------------------
115 // drive virtual machine
116 // ----------------------------------------------------------------------------
117
118 void VM::reset()
119 {
120         // reset all devices
121         for(DEVICE* device = first_device; device; device = device->next_device) {
122                 device->reset();
123         }
124 }
125
126 void VM::run()
127 {
128         event->drive();
129 }
130
131 // ----------------------------------------------------------------------------
132 // debugger
133 // ----------------------------------------------------------------------------
134
135 #ifdef USE_DEBUGGER
136 DEVICE *VM::get_cpu(int index)
137 {
138         if(index == 0) {
139                 return cpu;
140         }
141         return NULL;
142 }
143 #endif
144
145 // ----------------------------------------------------------------------------
146 // draw screen
147 // ----------------------------------------------------------------------------
148
149 void VM::draw_screen()
150 {
151         io->draw_screen();
152 }
153
154 // ----------------------------------------------------------------------------
155 // soud manager
156 // ----------------------------------------------------------------------------
157
158 void VM::initialize_sound(int rate, int samples)
159 {
160         // init sound manager
161         event->initialize_sound(rate, samples);
162 }
163
164 uint16* VM::create_sound(int* extra_frames)
165 {
166         return event->create_sound(extra_frames);
167 }
168
169 int VM::get_sound_buffer_ptr()
170 {
171         return event->get_sound_buffer_ptr();
172 }
173
174 #ifdef USE_SOUND_VOLUME
175 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
176 {
177         if(ch == 0) {
178                 drec->set_volume(0, decibel_l, decibel_r);
179         }
180 }
181 #endif
182
183 // ----------------------------------------------------------------------------
184 // notify key
185 // ----------------------------------------------------------------------------
186
187 void VM::key_down(int code, bool repeat)
188 {
189         if(!repeat) {
190                 io->key_down(code);
191         }
192 }
193
194 void VM::key_up(int code)
195 {
196         io->key_up();
197 }
198
199 // ----------------------------------------------------------------------------
200 // user interface
201 // ----------------------------------------------------------------------------
202
203 void VM::play_tape(const _TCHAR* file_path)
204 {
205         io->close_tape();
206         drec->play_tape(file_path);
207 }
208
209 void VM::rec_tape(const _TCHAR* file_path)
210 {
211         drec->close_tape();
212         io->rec_tape(file_path);
213 }
214
215 void VM::close_tape()
216 {
217         drec->close_tape();
218         io->close_tape();
219 }
220
221 bool VM::is_tape_inserted()
222 {
223         return drec->is_tape_inserted() || io->is_tape_inserted();
224 }
225
226 bool VM::is_tape_playing()
227 {
228         return drec->is_tape_playing();
229 }
230
231 bool VM::is_tape_recording()
232 {
233         return drec->is_tape_recording();
234 }
235
236 int VM::get_tape_position()
237 {
238         return drec->get_tape_position();
239 }
240
241 bool VM::is_frame_skippable()
242 {
243         return event->is_frame_skippable();
244 }
245
246 void VM::update_config()
247 {
248         for(DEVICE* device = first_device; device; device = device->next_device) {
249                 device->update_config();
250         }
251 }
252
253 #define STATE_VERSION   1
254
255 void VM::save_state(FILEIO* state_fio)
256 {
257         state_fio->FputUint32(STATE_VERSION);
258         
259         for(DEVICE* device = first_device; device; device = device->next_device) {
260                 device->save_state(state_fio);
261         }
262         state_fio->Fwrite(ram, sizeof(ram), 1);
263 }
264
265 bool VM::load_state(FILEIO* state_fio)
266 {
267         if(state_fio->FgetUint32() != STATE_VERSION) {
268                 return false;
269         }
270         for(DEVICE* device = first_device; device; device = device->next_device) {
271                 if(!device->load_state(state_fio)) {
272                         return false;
273                 }
274         }
275         state_fio->Fread(ram, sizeof(ram), 1);
276         return true;
277 }
278