OSDN Git Service

[VM][STATE] Apply New framework to some VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pv1000 / pv1000.cpp
1 /*
2         CASIO PV-1000 Emulator 'ePV-1000'
3
4         Author : Takeda.Toshiya
5         Date   : 2006.11.16 -
6
7         [ virtual machine ]
8 */
9
10 #include "pv1000.h"
11 #include "../../emu.h"
12 #include "../device.h"
13 #include "../event.h"
14
15 #include "../io.h"
16 #include "../memory.h"
17 #include "../z80.h"
18
19 #ifdef USE_DEBUGGER
20 #include "../debugger.h"
21 #endif
22
23 #include "joystick.h"
24 #include "psg.h"
25 #include "vdp.h"
26
27 // ----------------------------------------------------------------------------
28 // initialize
29 // ----------------------------------------------------------------------------
30
31 VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
32 {
33         // create devices
34         first_device = last_device = NULL;
35         dummy = new DEVICE(this, emu);  // must be 1st device
36         event = new EVENT(this, emu);   // must be 2nd device
37         dummy->set_device_name(_T("1st Dummy"));
38         
39         io = new IO(this, emu);
40         memory = new MEMORY(this, emu);
41         cpu = new Z80(this, emu);
42         
43         joystick = new JOYSTICK(this, emu);
44         psg = new PSG(this, emu);
45         vdp = new VDP(this, emu);
46         
47         // set contexts
48         event->set_context_cpu(cpu);
49         event->set_context_sound(psg);
50         
51         vdp->set_context_cpu(cpu);
52         vdp->set_memory_ptr(mem);
53         
54         // cpu bus
55         cpu->set_context_mem(memory);
56         cpu->set_context_io(io);
57         cpu->set_context_intr(dummy);
58 #ifdef USE_DEBUGGER
59         cpu->set_context_debugger(new DEBUGGER(this, emu));
60 #endif
61         
62         // memory bus
63         memset(mem, 0xff, 0x8000);
64         memset(mem + 0x8000, 0, 0x8000);
65         
66         memory->set_memory_r(0x0000, 0x7fff, mem);
67         memory->set_memory_rw(0xb800, 0xbfff, mem + 0xb800);
68         
69         // i/o bus
70         io->set_iomap_range_w(0xf8, 0xfa, psg);
71         io->set_iomap_range_rw(0xfc, 0xfd, joystick);
72         io->set_iomap_range_w(0xfe, 0xff, vdp);
73         
74         // initialize all devices
75 #if defined(__GIT_REPO_VERSION)
76         strncpy(_git_revision, __GIT_REPO_VERSION, sizeof(_git_revision) - 1);
77 #endif
78         for(DEVICE* device = first_device; device; device = device->next_device) {
79                 device->initialize();
80         }
81         inserted = false;
82 }
83
84 VM::~VM()
85 {
86         // delete all devices
87         for(DEVICE* device = first_device; device;) {
88                 DEVICE *next_device = device->next_device;
89                 device->release();
90                 delete device;
91                 device = next_device;
92         }
93 }
94
95 DEVICE* VM::get_device(int id)
96 {
97         for(DEVICE* device = first_device; device; device = device->next_device) {
98                 if(device->this_device_id == id) {
99                         return device;
100                 }
101         }
102         return NULL;
103 }
104
105 // ----------------------------------------------------------------------------
106 // drive virtual machine
107 // ----------------------------------------------------------------------------
108
109 void VM::reset()
110 {
111         // reset all devices
112         for(DEVICE* device = first_device; device; device = device->next_device) {
113                 device->reset();
114         }
115 }
116
117 void VM::run()
118 {
119         event->drive();
120 }
121
122 // ----------------------------------------------------------------------------
123 // debugger
124 // ----------------------------------------------------------------------------
125
126 #ifdef USE_DEBUGGER
127 DEVICE *VM::get_cpu(int index)
128 {
129         if(index == 0) {
130                 return cpu;
131         }
132         return NULL;
133 }
134 #endif
135
136 // ----------------------------------------------------------------------------
137 // draw screen
138 // ----------------------------------------------------------------------------
139
140 void VM::draw_screen()
141 {
142         vdp->draw_screen();
143 }
144
145 // ----------------------------------------------------------------------------
146 // soud manager
147 // ----------------------------------------------------------------------------
148
149 void VM::initialize_sound(int rate, int samples)
150 {
151         // init sound manager
152         event->initialize_sound(rate, samples);
153         
154         // init sound gen
155         psg->initialize_sound(rate);
156 }
157
158 uint16_t* VM::create_sound(int* extra_frames)
159 {
160         return event->create_sound(extra_frames);
161 }
162
163 int VM::get_sound_buffer_ptr()
164 {
165         return event->get_sound_buffer_ptr();
166 }
167
168 #ifdef USE_SOUND_VOLUME
169 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
170 {
171         if(ch == 0) {
172                 psg->set_volume(0, decibel_l, decibel_r);
173         }
174 }
175 #endif
176
177 // ----------------------------------------------------------------------------
178 // user interface
179 // ----------------------------------------------------------------------------
180
181 void VM::open_cart(int drv, const _TCHAR* file_path)
182 {
183         if(drv == 0) {
184                 memset(mem, 0xff, 0x8000);
185                 inserted = memory->read_image(file_path, mem, 0x8000);
186                 reset();
187         }
188 }
189
190 void VM::close_cart(int drv)
191 {
192         if(drv == 0) {
193                 memset(mem, 0xff, 0x8000);
194                 inserted = false;
195                 reset();
196         }
197 }
198
199 bool VM::is_cart_inserted(int drv)
200 {
201         if(drv == 0) {
202                 return inserted;
203         } else {
204                 return false;
205         }
206 }
207
208 bool VM::is_frame_skippable()
209 {
210         return event->is_frame_skippable();
211 }
212
213 void VM::update_config()
214 {
215         for(DEVICE* device = first_device; device; device = device->next_device) {
216                 device->update_config();
217         }
218 }
219
220 #define STATE_VERSION   2
221
222
223 bool VM::process_state(FILEIO* state_fio, bool loading)
224 {
225         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
226                 return false;
227         }
228         for(DEVICE* device = first_device; device; device = device->next_device) {
229                 // Note: typeid(foo).name is fixed by recent ABI.Not dec 6.
230                 // const char *name = typeid(*device).name();
231                 //       But, using get_device_name() instead of typeid(foo).name() 20181008 K.O
232                 const char *name = device->get_device_name();
233                 int len = strlen(name);
234                 
235                 if(!state_fio->StateCheckInt32(len)) {
236                         if(loading) {
237                                 printf("Class name len Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name);
238                         }
239                         return false;
240                 }
241                 if(!state_fio->StateCheckBuffer(name, len, 1)) {
242                         if(loading) {
243                                 printf("Class name Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name);
244                         }
245                         return false;
246                 }
247                 if(!device->process_state(state_fio, loading)) {
248                         if(loading) {
249                                 printf("Data loading Error: DEVID=%d\n", device->this_device_id);
250                         }
251                         return false;
252                 }
253         }
254         // Machine specified.
255         state_fio->StateBuffer(mem, sizeof(mem), 1);
256         state_fio->StateBool(inserted);
257         return true;
258 }