OSDN Git Service

[General][Qt] Merge upstream, datarecorder with sound.
[csp-qt/common_source_project-fm7.git] / source / src / vm / hc40 / hc40.cpp
1 /*
2         EPSON HC-40 Emulator 'eHC-40'
3
4         Author : Takeda.Toshiya
5         Date   : 2008.02.23 -
6
7         [ virtual machine ]
8 */
9
10 #include "hc40.h"
11 #include "../../emu.h"
12 #include "../device.h"
13 #include "../event.h"
14
15 #include "../beep.h"
16 #include "../datarec.h"
17 #include "../ptf20.h"
18 #include "../z80.h"
19
20 #ifdef USE_DEBUGGER
21 #include "../debugger.h"
22 #endif
23
24 #include "io.h"
25 #include "memory.h"
26
27 #include "../../fileio.h"
28
29 // ----------------------------------------------------------------------------
30 // initialize
31 // ----------------------------------------------------------------------------
32
33 VM::VM(EMU* parent_emu) : emu(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         
40         beep = new BEEP(this, emu);
41         drec = new DATAREC(this, emu);
42         tf20 = new PTF20(this, emu);
43         cpu = new Z80(this, emu);
44         
45         io = new IO(this, emu);
46         memory = new MEMORY(this, emu);
47         
48         // set contexts
49         event->set_context_cpu(cpu);
50         event->set_context_sound(beep);
51         event->set_context_sound(drec);
52         
53         drec->set_context_out(io, SIG_IO_DREC, 1);
54         tf20->set_context_sio(io, SIG_IO_ART);
55         
56         io->set_context_cpu(cpu);
57         io->set_context_mem(memory, memory->get_ram());
58         io->set_context_tf20(tf20);
59         io->set_context_beep(beep);
60         io->set_context_drec(drec);
61         
62         // cpu bus
63         cpu->set_context_mem(memory);
64         cpu->set_context_io(io);
65         cpu->set_context_intr(io);
66 #ifdef USE_DEBUGGER
67         cpu->set_context_debugger(new DEBUGGER(this, emu));
68 #endif
69         
70         // initialize all devices
71         for(DEVICE* device = first_device; device; device = device->next_device) {
72                 device->initialize();
73         }
74 }
75
76 VM::~VM()
77 {
78         // delete all devices
79         for(DEVICE* device = first_device; device;) {
80                 DEVICE *next_device = device->next_device;
81                 device->release();
82                 delete device;
83                 device = next_device;
84         }
85 }
86
87 DEVICE* VM::get_device(int id)
88 {
89         for(DEVICE* device = first_device; device; device = device->next_device) {
90                 if(device->this_device_id == id) {
91                         return device;
92                 }
93         }
94         return NULL;
95 }
96
97 // ----------------------------------------------------------------------------
98 // drive virtual machine
99 // ----------------------------------------------------------------------------
100
101 void VM::reset()
102 {
103         // reset all devices
104         for(DEVICE* device = first_device; device; device = device->next_device) {
105                 device->reset();
106         }
107 }
108
109 void VM::special_reset()
110 {
111         // system reset
112         for(DEVICE* device = first_device; device; device = device->next_device) {
113                 device->reset();
114         }
115         io->sysreset();
116 }
117
118 void VM::run()
119 {
120         event->drive();
121 }
122
123 // ----------------------------------------------------------------------------
124 // debugger
125 // ----------------------------------------------------------------------------
126
127 #ifdef USE_DEBUGGER
128 DEVICE *VM::get_cpu(int index)
129 {
130         if(index == 0) {
131                 return cpu;
132         }
133         return NULL;
134 }
135 #endif
136
137 // ----------------------------------------------------------------------------
138 // draw screen
139 // ----------------------------------------------------------------------------
140
141 void VM::draw_screen()
142 {
143         io->draw_screen();
144 }
145
146 int VM::access_lamp()
147 {
148         uint32 status = tf20->read_signal(0);
149         return (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0;
150 }
151
152 // ----------------------------------------------------------------------------
153 // soud manager
154 // ----------------------------------------------------------------------------
155
156 void VM::initialize_sound(int rate, int samples)
157 {
158         // init sound manager
159         event->initialize_sound(rate, samples);
160         
161         // init sound gen
162         beep->init(rate, 1000, 8000);
163 }
164
165 uint16* VM::create_sound(int* extra_frames)
166 {
167         return event->create_sound(extra_frames);
168 }
169
170 int VM::sound_buffer_ptr()
171 {
172         return event->sound_buffer_ptr();
173 }
174
175 // ----------------------------------------------------------------------------
176 // notify key
177 // ----------------------------------------------------------------------------
178
179 void VM::key_down(int code, bool repeat)
180 {
181         io->key_down(code);
182 }
183
184 void VM::key_up(int code)
185 {
186         io->key_up(code);
187 }
188
189 // ----------------------------------------------------------------------------
190 // user interface
191 // ----------------------------------------------------------------------------
192
193 void VM::open_disk(int drv, _TCHAR* file_path, int bank)
194 {
195         tf20->open_disk(drv, file_path, bank);
196 }
197
198 void VM::close_disk(int drv)
199 {
200         tf20->close_disk(drv);
201 }
202
203 bool VM::disk_inserted(int drv)
204 {
205         return tf20->disk_inserted(drv);
206 }
207
208 void VM::play_tape(_TCHAR* file_path)
209 {
210         drec->play_tape(file_path);
211 }
212
213 void VM::rec_tape(_TCHAR* file_path)
214 {
215         drec->rec_tape(file_path);
216 }
217
218 void VM::close_tape()
219 {
220         drec->close_tape();
221 }
222
223 bool VM::tape_inserted()
224 {
225         return drec->tape_inserted();
226 }
227
228 bool VM::now_skip()
229 {
230         return event->now_skip();
231 }
232
233 void VM::update_config()
234 {
235         for(DEVICE* device = first_device; device; device = device->next_device) {
236                 device->update_config();
237         }
238 }
239
240 #define STATE_VERSION   1
241
242 void VM::save_state(FILEIO* state_fio)
243 {
244         state_fio->FputUint32(STATE_VERSION);
245         
246         for(DEVICE* device = first_device; device; device = device->next_device) {
247                 device->save_state(state_fio);
248         }
249 }
250
251 bool VM::load_state(FILEIO* state_fio)
252 {
253         if(state_fio->FgetUint32() != STATE_VERSION) {
254                 return false;
255         }
256         for(DEVICE* device = first_device; device; device = device->next_device) {
257                 if(!device->load_state(state_fio)) {
258                         return false;
259                 }
260         }
261         return true;
262 }
263