OSDN Git Service

d1ead08dac5bfe3946341023ae1513c6c5220587
[csp-qt/common_source_project-fm7.git] / source / src / vm / scv / scv.cpp
1 /*
2         EPOCH Super Cassette Vision Emulator 'eSCV'
3
4         Author : Takeda.Toshiya
5         Date   : 2006.08.21 -
6
7         [ virtual machine ]
8 */
9
10 #include "scv.h"
11 #include "../../emu.h"
12 #include "../device.h"
13 #include "../event.h"
14
15 #include "../upd7801.h"
16
17 #ifdef USE_DEBUGGER
18 #include "../debugger.h"
19 #endif
20
21 #include "io.h"
22 #include "memory.h"
23 #include "sound.h"
24 #include "vdp.h"
25
26 // ----------------------------------------------------------------------------
27 // initialize
28 // ----------------------------------------------------------------------------
29
30 VM::VM(EMU* parent_emu) : VM_TEMPLATE(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         dummy->set_device_name(_T("1st Dummy"));
37         cpu = new UPD7801(this, emu);
38         
39         io = new IO(this, emu);
40         memory = new MEMORY(this, emu);
41         sound = new SOUND(this, emu);
42         vdp = new VDP(this, emu);
43         
44         // set contexts
45         event->set_context_cpu(cpu);
46         event->set_context_sound(sound);
47         
48         io->set_context_mem(memory);
49         io->set_context_sound(sound);
50         memory->set_context_sound(sound);
51         sound->set_context_cpu(cpu);
52         vdp->set_context_cpu(cpu);
53         vdp->set_font_ptr(memory->get_font());
54         vdp->set_vram_ptr(memory->get_vram());
55         
56         // cpu bus
57         cpu->set_context_mem(memory);
58         cpu->set_context_io(io);
59 #ifdef USE_DEBUGGER
60         cpu->set_context_debugger(new DEBUGGER(this, emu));
61 #endif
62         
63         // initialize all devices
64         for(DEVICE* device = first_device; device; device = device->next_device) {
65                 device->initialize();
66         }
67         decl_state();
68 }
69
70 VM::~VM()
71 {
72         // delete all devices
73         for(DEVICE* device = first_device; device;) {
74                 DEVICE *next_device = device->next_device;
75                 device->release();
76                 delete device;
77                 device = next_device;
78         }
79 }
80
81 DEVICE* VM::get_device(int id)
82 {
83         for(DEVICE* device = first_device; device; device = device->next_device) {
84                 if(device->this_device_id == id) {
85                         return device;
86                 }
87         }
88         return NULL;
89 }
90
91 // ----------------------------------------------------------------------------
92 // drive virtual machine
93 // ----------------------------------------------------------------------------
94
95 void VM::reset()
96 {
97         // reset all devices
98         for(DEVICE* device = first_device; device; device = device->next_device) {
99                 device->reset();
100         }
101 }
102
103 void VM::run()
104 {
105         event->drive();
106 }
107
108 // ----------------------------------------------------------------------------
109 // debugger
110 // ----------------------------------------------------------------------------
111
112 #ifdef USE_DEBUGGER
113 DEVICE *VM::get_cpu(int index)
114 {
115         if(index == 0) {
116                 return cpu;
117         }
118         return NULL;
119 }
120 #endif
121
122 // ----------------------------------------------------------------------------
123 // draw screen
124 // ----------------------------------------------------------------------------
125
126 void VM::draw_screen()
127 {
128         vdp->draw_screen();
129 }
130
131 // ----------------------------------------------------------------------------
132 // soud manager
133 // ----------------------------------------------------------------------------
134
135 void VM::initialize_sound(int rate, int samples)
136 {
137         // init sound manager
138         event->initialize_sound(rate, samples);
139         
140         // init sound gen
141         sound->initialize_sound(rate);
142 }
143
144 uint16_t* VM::create_sound(int* extra_frames)
145 {
146         return event->create_sound(extra_frames);
147 }
148
149 int VM::get_sound_buffer_ptr()
150 {
151         return event->get_sound_buffer_ptr();
152 }
153
154 #ifdef USE_SOUND_VOLUME
155 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
156 {
157         sound->set_volume(ch, decibel_l, decibel_r);
158 }
159 #endif
160
161 // ----------------------------------------------------------------------------
162 // user interface
163 // ----------------------------------------------------------------------------
164
165 void VM::open_cart(int drv, const _TCHAR* file_path)
166 {
167         if(drv == 0) {
168                 memory->open_cart(file_path);
169                 reset();
170         }
171 }
172
173 void VM::close_cart(int drv)
174 {
175         if(drv == 0) {
176                 memory->close_cart();
177                 reset();
178         }
179 }
180
181 bool VM::is_cart_inserted(int drv)
182 {
183         if(drv == 0) {
184                 return memory->is_cart_inserted();
185         } else {
186                 return false;
187         }
188 }
189
190 bool VM::is_frame_skippable()
191 {
192         return event->is_frame_skippable();
193 }
194
195 void VM::update_config()
196 {
197         for(DEVICE* device = first_device; device; device = device->next_device) {
198                 device->update_config();
199         }
200 }
201
202 #define STATE_VERSION   2
203
204 #include "../../statesub.h"
205 #include "../../qt/gui/csp_logger.h"
206 extern CSP_Logger DLL_PREFIX_I *csp_logger;
207
208 void VM::decl_state(void)
209 {
210         state_entry = new csp_state_utils(STATE_VERSION, 0, (_TCHAR *)(_T("CSP::SCV_HEAD")), csp_logger);
211         for(DEVICE* device = first_device; device; device = device->next_device) {
212                 device->decl_state();
213         }
214 }
215
216 void VM::save_state(FILEIO* state_fio)
217 {
218         //state_fio->FputUint32(STATE_VERSION);
219         
220         if(state_entry != NULL) {
221                 state_entry->save_state(state_fio);
222         }
223         for(DEVICE* device = first_device; device; device = device->next_device) {
224                 device->save_state(state_fio);
225         }
226 }
227
228 bool VM::load_state(FILEIO* state_fio)
229 {
230         //if(state_fio->FgetUint32() != STATE_VERSION) {
231         //      return false;
232         //}
233         bool mb = false;
234         if(state_entry != NULL) {
235                 mb = state_entry->load_state(state_fio);
236         }
237         if(!mb) {
238                 emu->out_debug_log("INFO: HEADER DATA ERROR");
239                 return false;
240         }
241         for(DEVICE* device = first_device; device; device = device->next_device) {
242                 if(!device->load_state(state_fio)) {
243                         return false;
244                 }
245         }
246         return true;
247 }
248