OSDN Git Service

[VM][STATE] Apply New framework to some VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pv2000 / pv2000.cpp
1 /*
2         CASIO PV-2000 Emulator 'EmuGaki'
3
4         Author : Takeda.Toshiya
5         Date   : 2006.08.18 -
6
7         [ virtual machine ]
8 */
9
10 #include "pv2000.h"
11 #include "../../emu.h"
12 #include "../device.h"
13 #include "../event.h"
14
15 #include "../io.h"
16 #include "../memory.h"
17 #include "../sn76489an.h"
18 #include "../tms9918a.h"
19 #include "../z80.h"
20
21 #ifdef USE_DEBUGGER
22 #include "../debugger.h"
23 #endif
24
25 #include "cmt.h"
26 #include "keyboard.h"
27 #include "printer.h"
28
29 // ----------------------------------------------------------------------------
30 // initialize
31 // ----------------------------------------------------------------------------
32
33 VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
34 {
35         // create devices
36         first_device = last_device = NULL;
37         dummy = new DEVICE(this, emu);  // must be 1st device
38         event = new EVENT(this, emu);   // must be 2nd device
39         dummy->set_device_name(_T("1st Dummy"));
40         
41         io = new IO(this, emu);
42         memory = new MEMORY(this, emu);
43         psg = new SN76489AN(this, emu);
44         vdp = new TMS9918A(this, emu);
45         cpu = new Z80(this, emu);
46         cmt = new CMT(this, emu);
47         key = new KEYBOARD(this, emu);
48         prt = new PRINTER(this, emu);
49         // set contexts
50         event->set_context_cpu(cpu);
51         event->set_context_sound(psg);
52         
53         vdp->set_context_irq(cpu, SIG_CPU_NMI, 1);
54         key->set_context_cpu(cpu);
55         
56         // cpu bus
57         cpu->set_context_mem(memory);
58         cpu->set_context_io(io);
59         cpu->set_context_intr(dummy);
60 #ifdef USE_DEBUGGER
61         cpu->set_context_debugger(new DEBUGGER(this, emu));
62 #endif
63         
64         // memory bus
65         memset(ram, 0, sizeof(ram));
66         memset(ext, 0, sizeof(ext));
67         memset(ipl, 0xff, sizeof(ipl));
68         memset(cart, 0xff, sizeof(cart));
69         
70         memory->read_bios(_T("IPL.ROM"), ipl, sizeof(ipl));
71         
72         memory->set_memory_r(0x0000, 0x3fff, ipl);
73         memory->set_memory_mapped_io_rw(0x4000, 0x4fff, vdp);
74         memory->set_memory_rw(0x7000, 0x7fff, ram);
75         memory->set_memory_rw(0x8000, 0xbfff, ext);
76         memory->set_memory_r(0xc000, 0xffff, cart);
77         
78         // i/o bus
79         io->set_iomap_single_w(0x00, cmt);
80         io->set_iomap_single_r(0x10, key);
81         io->set_iomap_single_rw(0x20, key);
82         io->set_iomap_single_r(0x40, key);
83         io->set_iomap_single_w(0x40, psg);
84         io->set_iomap_single_rw(0x60, cmt);
85         io->set_iomap_single_w(0x80, prt);
86         io->set_iomap_single_r(0x90, prt);
87         io->set_iomap_single_w(0xa0, prt);
88         io->set_iomap_single_w(0xb0, prt);
89         
90         // initialize all devices
91 #if defined(__GIT_REPO_VERSION)
92         strncpy(_git_revision, __GIT_REPO_VERSION, sizeof(_git_revision) - 1);
93 #endif
94         for(DEVICE* device = first_device; device; device = device->next_device) {
95                 device->initialize();
96         }
97         inserted = false;
98 }
99
100 VM::~VM()
101 {
102         // delete all devices
103         for(DEVICE* device = first_device; device;) {
104                 DEVICE *next_device = device->next_device;
105                 device->release();
106                 delete device;
107                 device = next_device;
108         }
109 }
110
111 DEVICE* VM::get_device(int id)
112 {
113         for(DEVICE* device = first_device; device; device = device->next_device) {
114                 if(device->this_device_id == id) {
115                         return device;
116                 }
117         }
118         return NULL;
119 }
120
121 // ----------------------------------------------------------------------------
122 // drive virtual machine
123 // ----------------------------------------------------------------------------
124
125 void VM::reset()
126 {
127         // reset all devices
128         for(DEVICE* device = first_device; device; device = device->next_device) {
129                 device->reset();
130         }
131 }
132
133 void VM::run()
134 {
135         event->drive();
136 }
137
138 // ----------------------------------------------------------------------------
139 // debugger
140 // ----------------------------------------------------------------------------
141
142 #ifdef USE_DEBUGGER
143 DEVICE *VM::get_cpu(int index)
144 {
145         if(index == 0) {
146                 return cpu;
147         }
148         return NULL;
149 }
150 #endif
151
152 // ----------------------------------------------------------------------------
153 // draw screen
154 // ----------------------------------------------------------------------------
155
156 void VM::draw_screen()
157 {
158         vdp->draw_screen();
159 }
160
161 // ----------------------------------------------------------------------------
162 // soud manager
163 // ----------------------------------------------------------------------------
164
165 void VM::initialize_sound(int rate, int samples)
166 {
167         // init sound manager
168         event->initialize_sound(rate, samples);
169         
170         // init sound gen
171         psg->initialize_sound(rate, 3579545, 8000);
172 }
173
174 uint16_t* VM::create_sound(int* extra_frames)
175 {
176         return event->create_sound(extra_frames);
177 }
178
179 int VM::get_sound_buffer_ptr()
180 {
181         return event->get_sound_buffer_ptr();
182 }
183
184 #ifdef USE_SOUND_VOLUME
185 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
186 {
187         if(ch == 0) {
188                 psg->set_volume(0, decibel_l, decibel_r);
189         }
190 }
191 #endif
192
193 // ----------------------------------------------------------------------------
194 // notify key
195 // ----------------------------------------------------------------------------
196
197 void VM::key_down(int code, bool repeat)
198 {
199         key->key_down(code);
200 }
201
202 void VM::key_up(int code)
203 {
204         key->key_up(code);
205 }
206
207 // ----------------------------------------------------------------------------
208 // user interface
209 // ----------------------------------------------------------------------------
210
211 void VM::open_cart(int drv, const _TCHAR* file_path)
212 {
213         if(drv == 0) {
214                 memset(cart, 0xff, sizeof(cart));
215                 inserted = memory->read_image(file_path, cart, sizeof(cart));
216                 reset();
217         }
218 }
219
220 void VM::close_cart(int drv)
221 {
222         if(drv == 0) {
223                 memset(cart, 0xff, sizeof(cart));
224                 inserted = false;
225                 reset();
226         }
227 }
228
229 bool VM::is_cart_inserted(int drv)
230 {
231         if(drv == 0) {
232                 return inserted;
233         } else {
234                 return false;
235         }
236 }
237
238 void VM::play_tape(int drv, const _TCHAR* file_path)
239 {
240         cmt->play_tape(file_path);
241 }
242
243 void VM::rec_tape(int drv, const _TCHAR* file_path)
244 {
245         cmt->rec_tape(file_path);
246 }
247
248 void VM::close_tape(int drv)
249 {
250         cmt->close_tape();
251 }
252
253 bool VM::is_tape_inserted(int drv)
254 {
255         return cmt->is_tape_inserted();
256 }
257
258 bool VM::is_frame_skippable()
259 {
260         return event->is_frame_skippable();
261 }
262
263 void VM::update_config()
264 {
265         for(DEVICE* device = first_device; device; device = device->next_device) {
266                 device->update_config();
267         }
268 }
269
270 #define STATE_VERSION   2
271
272 bool VM::process_state(FILEIO* state_fio, bool loading)
273 {
274         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
275                 return false;
276         }
277         for(DEVICE* device = first_device; device; device = device->next_device) {
278                 // Note: typeid(foo).name is fixed by recent ABI.Not dec 6.
279                 // const char *name = typeid(*device).name();
280                 //       But, using get_device_name() instead of typeid(foo).name() 20181008 K.O
281                 const char *name = device->get_device_name();
282                 int len = strlen(name);
283                 
284                 if(!state_fio->StateCheckInt32(len)) {
285                         if(loading) {
286                                 printf("Class name len Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name);
287                         }
288                         return false;
289                 }
290                 if(!state_fio->StateCheckBuffer(name, len, 1)) {
291                         if(loading) {
292                                 printf("Class name Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name);
293                         }
294                         return false;
295                 }
296                 if(!device->process_state(state_fio, loading)) {
297                         if(loading) {
298                                 printf("Data loading Error: DEVID=%d\n", device->this_device_id);
299                         }
300                         return false;
301                 }
302         }
303         // Machine specified.
304         state_fio->StateBuffer(ram, sizeof(ram), 1);
305         state_fio->StateBuffer(ext, sizeof(ext), 1);
306         state_fio->StateBool(inserted);
307         return true;
308 }