OSDN Git Service

[VM][General] Merge upstream 2016-02-13. Still don't implement OSD/Gui part of joysti...
[csp-qt/common_source_project-fm7.git] / source / src / vm / z80tvgame / z80tvgame.cpp
1 /*
2         Homebrew Z80 TV GAME SYSTEM Emulator 'eZ80TVGAME'
3
4         Author : Takeda.Toshiya
5         Date   : 2015.04.28-
6
7         [ virtual machine ]
8 */
9
10 // http://w01.tp1.jp/~a571632211/z80tvgame/index.html
11
12 #include "z80tvgame.h"
13 #include "../../emu.h"
14 #include "../device.h"
15 #include "../event.h"
16
17 #ifdef _USE_I8255
18 #include "../i8255.h"
19 #else
20 #include "../z80pio.h"
21 #endif
22 #include "../pcm1bit.h"
23 #include "../z80.h"
24
25 #ifdef USE_DEBUGGER
26 #include "../debugger.h"
27 #endif
28
29 #include "joystick.h"
30 #include "memory.h"
31
32 // ----------------------------------------------------------------------------
33 // initialize
34 // ----------------------------------------------------------------------------
35
36 VM::VM(EMU* parent_emu) : emu(parent_emu)
37 {
38         // create devices
39         first_device = last_device = NULL;
40         dummy = new DEVICE(this, emu);  // must be 1st device
41         event = new EVENT(this, emu);   // must be 2nd device
42         
43 #ifdef _USE_I8255
44         pio = new I8255(this, emu);
45 #else
46         pio = new Z80PIO(this, emu);
47 #endif
48         pcm = new PCM1BIT(this, emu);
49         cpu = new Z80(this, emu);
50         
51         joystick = new JOYSTICK(this, emu);
52         memory = new MEMORY(this, emu);
53         
54         // set contexts
55         event->set_context_cpu(cpu);
56         event->set_context_sound(pcm);
57         
58 #ifdef _USE_I8255
59         pio->set_context_port_c(pcm, SIG_PCM1BIT_SIGNAL, 1, 0);
60 #else
61         pio->set_context_port_b(pcm, SIG_PCM1BIT_SIGNAL, 1, 0);
62 #endif
63         joystick->set_context_pio(pio);
64         
65         // cpu bus
66         cpu->set_context_mem(memory);
67         cpu->set_context_io(pio);
68         cpu->set_context_intr(dummy);
69 #ifdef USE_DEBUGGER
70         cpu->set_context_debugger(new DEBUGGER(this, emu));
71 #endif
72         
73         // initialize all devices
74         for(DEVICE* device = first_device; device; device = device->next_device) {
75                 device->initialize();
76         }
77 }
78
79 VM::~VM()
80 {
81         // delete all devices
82         for(DEVICE* device = first_device; device;) {
83                 DEVICE *next_device = device->next_device;
84                 device->release();
85                 delete device;
86                 device = next_device;
87         }
88 }
89
90 DEVICE* VM::get_device(int id)
91 {
92         for(DEVICE* device = first_device; device; device = device->next_device) {
93                 if(device->this_device_id == id) {
94                         return device;
95                 }
96         }
97         return NULL;
98 }
99
100 // ----------------------------------------------------------------------------
101 // debugger
102 // ----------------------------------------------------------------------------
103
104 #ifdef USE_DEBUGGER
105 DEVICE *VM::get_cpu(int index)
106 {
107         if(index == 0) {
108                 return cpu;
109         }
110         return NULL;
111 }
112 #endif
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 // draw screen
133 // ----------------------------------------------------------------------------
134
135 void VM::draw_screen()
136 {
137         memory->draw_screen();
138 }
139
140 // ----------------------------------------------------------------------------
141 // soud manager
142 // ----------------------------------------------------------------------------
143
144 void VM::initialize_sound(int rate, int samples)
145 {
146         // init sound manager
147         event->initialize_sound(rate, samples);
148         
149         // init sound gen
150         pcm->init(rate, 8000);
151 }
152
153 uint16* VM::create_sound(int* extra_frames)
154 {
155         return event->create_sound(extra_frames);
156 }
157
158 int VM::sound_buffer_ptr()
159 {
160         return event->sound_buffer_ptr();
161 }
162
163 #ifdef USE_SOUND_VOLUME
164 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
165 {
166         if(ch == 0) {
167                 pcm->set_volume(0, decibel_l, decibel_r);
168         }
169 }
170 #endif
171
172 // ----------------------------------------------------------------------------
173 // user interface
174 // ----------------------------------------------------------------------------
175
176 void VM::open_cart(int drv, const _TCHAR* file_path)
177 {
178         if(drv == 0) {
179                 memory->open_cart(file_path);
180                 reset();
181         }
182 }
183
184 void VM::close_cart(int drv)
185 {
186         if(drv == 0) {
187                 memory->close_cart();
188                 reset();
189         }
190 }
191
192 bool VM::cart_inserted(int drv)
193 {
194         if(drv == 0) {
195                 return memory->cart_inserted();
196         } else {
197                 return false;
198         }
199 }
200
201 bool VM::now_skip()
202 {
203         return event->now_skip();
204 }
205
206 void VM::update_config()
207 {
208         for(DEVICE* device = first_device; device; device = device->next_device) {
209                 device->update_config();
210         }
211 }
212
213 #define STATE_VERSION   1
214
215 void VM::save_state(FILEIO* state_fio)
216 {
217         state_fio->FputUint32(STATE_VERSION);
218         
219         for(DEVICE* device = first_device; device; device = device->next_device) {
220                 device->save_state(state_fio);
221         }
222 }
223
224 bool VM::load_state(FILEIO* state_fio)
225 {
226         if(state_fio->FgetUint32() != STATE_VERSION) {
227                 return false;
228         }
229         for(DEVICE* device = first_device; device; device = device->next_device) {
230                 if(!device->load_state(state_fio)) {
231                         return false;
232                 }
233         }
234         return true;
235 }
236