OSDN Git Service

969c01427f3c11cbca68bcfedcb2e8905550c594
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc8801 / pc8801.cpp
1
2 /*
3         NEC PC-8801MA Emulator 'ePC-8801MA'
4         NEC PC-8001mkIISR Emulator 'ePC-8001mkIISR'
5
6         Author : Takeda.Toshiya
7         Date   : 2012.02.16-
8
9         [ virtual machine ]
10 */
11
12 #include "pc8801.h"
13 #include "../../emu.h"
14 #include "../device.h"
15 #include "../event.h"
16
17 #include "../i8251.h"
18 #include "../i8255.h"
19 #include "../pcm1bit.h"
20 //#include "../pcpr201.h"
21 #include "../prnfile.h"
22 #include "../upd1990a.h"
23 #include "../ym2203.h"
24 #include "../z80.h"
25
26 #include "../disk.h"
27 #include "../noise.h"
28 #include "../pc80s31k.h"
29 #include "../upd765a.h"
30
31 #ifdef USE_DEBUGGER
32 #include "../debugger.h"
33 #endif
34
35 #ifdef SUPPORT_PC88_CDROM
36 #include "../scsi_cdrom.h"
37 #include "../scsi_host.h"
38 #endif
39
40 #ifdef SUPPORT_PC88_HMB20
41 #include "../ym2151.h"
42 #endif
43
44 #ifdef SUPPORT_PC88_PCG8100
45 #include "../i8253.h"
46 #endif
47
48 #include "pc88.h"
49
50 using PC88DEV::PC88;
51 // ----------------------------------------------------------------------------
52 // initialize
53 // ----------------------------------------------------------------------------
54
55 VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu)
56 {
57         // check configs
58         boot_mode = config.boot_mode;
59         
60         // create devices
61         first_device = last_device = NULL;
62         dummy = new DEVICE(this, emu);  // must be 1st device
63         
64         pc88event = new EVENT(this, emu);
65 //      pc88event->set_device_name(_T("Event Manager (PC-8801)"));
66 //      pc88event->set_frames_per_sec(60);
67 //      pc88event->set_lines_per_frame(260);
68         
69         pc88 = new PC88(this, emu);
70 //      pc88->set_context_event_manager(pc88event);
71         pc88sio = new I8251(this, emu);
72 //      pc88sio->set_device_name(_T("8251 SIO (PC-8801)"));
73 //      pc88sio->set_context_event_manager(pc88event);
74         pc88pio = new I8255(this, emu);
75 //      pc88pio->set_device_name(_T("8255 PIO (PC-8801)"));
76 //      pc88pio->set_context_event_manager(pc88event);
77         pc88pcm = new PCM1BIT(this, emu);
78 //      pc88pcm->set_device_name(_T("1-Bit PCM Sound (PC-8801)"));
79 //      pc88pcm->set_context_event_manager(pc88event);
80         pc88rtc = new UPD1990A(this, emu);
81 //      pc88rtc->set_device_name(_T("uPD1990A RTC (PC-8801)"));
82 //      pc88rtc->set_context_event_manager(pc88event);
83         // config.sound_type
84         //      0: 44h:OPNA A4h:None            PC-8801FH/MH or later
85         //      1: 44h:OPN  A4h:None            PC-8801mkIISR/TR/FR/MR
86         //      2: 44h:OPN  A4h:OPNA            PC-8801mkIISR/TR/FR/MR + PC-8801-23
87         //      3: 44h:OPN  A4h:OPN             PC-8801mkIISR/TR/FR/MR + PC-8801-11
88         //      4: 44h:OPNA A4h:OPNA            PC-8801FH/MH or later  + PC-8801-24
89         //      5: 44h:OPNA A4h:OPN             PC-8801FH/MH or later  + PC-8801-11
90         pc88opn = new YM2203(this, emu);
91 //      pc88opn->set_context_event_manager(pc88event);
92 #ifdef USE_SOUND_TYPE
93 #ifdef SUPPORT_PC88_OPNA
94         if(config.sound_type == 0 || config.sound_type == 4 || config.sound_type == 5) {
95                 pc88opn->is_ym2608 = true;
96                 pc88opn->set_device_name(_T("YM2608 OPNA"));
97         } else {
98 #endif
99                 pc88opn->is_ym2608 = false;
100                 pc88opn->set_device_name(_T("YM2203 OPN"));
101 #ifdef SUPPORT_PC88_OPNA
102         }
103 #endif
104 #ifdef SUPPORT_PC88_SB2
105         if(config.sound_type >= 2) {
106                 pc88sb2 = new YM2203(this, emu);
107 //              pc88sb2->set_context_event_manager(pc88event);
108 #ifdef SUPPORT_PC88_OPNA
109                 if(config.sound_type == 2 || config.sound_type == 4) {
110                         pc88sb2->is_ym2608 = true;
111                         pc88sb2->set_device_name(_T("YM2608 OPNA (SB2)"));
112                 } else {
113 #endif
114                         pc88sb2->is_ym2608 = false;
115                         pc88sb2->set_device_name(_T("YM2203 OPN (SB2)"));
116 #ifdef SUPPORT_PC88_OPNA
117                 }
118 #endif
119         } else {
120                 pc88sb2 = NULL;
121         }
122 #endif
123 #endif
124         if(config.printer_type == 0) {
125                 pc88prn = new PRNFILE(this, emu);
126 //              pc88prn->set_context_event_manager(pc88event);
127 //      } else if(config.printer_type == 1) {
128 //              pc88prn = new PCPR201(this, emu);
129 //              pc88prn->set_context_event_manager(pc88event);
130         } else {
131                 pc88prn = dummy;
132         }
133         pc88cpu = new Z80(this, emu);
134 //      pc88cpu->set_context_event_manager(pc88event);
135         
136         pc88sub = new PC80S31K(this, emu);
137         pc88sub->set_device_name(_T("PC-80S31K (Sub)"));
138 //      pc88sub->set_context_event_manager(pc88event);
139         pc88pio_sub = new I8255(this, emu);
140         pc88pio_sub->set_device_name(_T("8255 PIO (Sub)"));
141 //      pc88pio_sub->set_context_event_manager(pc88event);
142         pc88fdc_sub = new UPD765A(this, emu);
143         pc88fdc_sub->set_device_name(_T("uPD765A FDC (Sub)"));
144 //      pc88fdc_sub->set_context_event_manager(pc88event);
145         pc88noise_seek = new NOISE(this, emu);
146 //      pc88noise_seek->set_context_event_manager(pc88event);
147         pc88noise_head_down = new NOISE(this, emu);
148 //      pc88noise_head_down->set_context_event_manager(pc88event);
149         pc88noise_head_up = new NOISE(this, emu);
150 //      pc88noise_head_up->set_context_event_manager(pc88event);
151         pc88cpu_sub = new Z80(this, emu);
152         pc88cpu_sub->set_device_name(_T("Z80 CPU (Sub)"));
153 //      pc88cpu_sub->set_context_event_manager(pc88event);
154         
155 #ifdef SUPPORT_PC88_CDROM
156         pc88scsi_host = new SCSI_HOST(this, emu);
157 //      pc88scsi_host->set_context_event_manager(pc88event);
158         pc88scsi_cdrom = new SCSI_CDROM(this, emu);
159 //      pc88scsi_cdrom->set_context_event_manager(pc88event);
160 #endif
161         
162 #ifdef SUPPORT_PC88_HMB20
163         pc88opm = new YM2151(this, emu);
164         pc88opm->set_device_name(_T("YM2151 OPM (HMB20)"));
165 //      pc88opm->set_context_event_manager(pc88event);
166 #endif
167         
168 #ifdef SUPPORT_PC88_PCG8100
169         pc88pit = new I8253(this, emu);
170         pc88pit->set_device_name(_T("8253 PIT (PCG8100)"));
171 //      pc88pit->set_context_event_manager(pc88event);
172         pc88pcm0 = new PCM1BIT(this, emu);
173         pc88pcm0->set_device_name(_T("1-Bit PCM Sound (PCG8100 #1)"));
174 //      pc88pcm0->set_context_event_manager(pc88event);
175         pc88pcm1 = new PCM1BIT(this, emu);
176         pc88pcm1->set_device_name(_T("1-Bit PCM Sound (PCG8100 #2)"));
177 //      pc88pcm1->set_context_event_manager(pc88event);
178         pc88pcm2 = new PCM1BIT(this, emu);
179         pc88pcm2->set_device_name(_T("1-Bit PCM Sound (PCG8100 #3)"));
180 //      pc88pcm2->set_context_event_manager(pc88event);
181 #endif
182         
183 #ifdef SUPPORT_PC88_HIGH_CLOCK
184         pc88event->set_context_cpu(pc88cpu, (config.cpu_type == 1) ? 3993624 : 7987248);
185 #else
186         pc88event->set_context_cpu(pc88cpu, 3993624);
187 #endif
188         pc88event->set_context_cpu(pc88cpu_sub, 3993624);
189         pc88event->set_context_sound(pc88opn);
190 #ifdef SUPPORT_PC88_SB2
191         if(pc88sb2 != NULL) {
192                 pc88event->set_context_sound(pc88sb2);
193         }
194 #endif
195         pc88event->set_context_sound(pc88pcm);
196 #ifdef SUPPORT_PC88_CDROM
197         pc88event->set_context_sound(pc88scsi_cdrom);
198 #endif
199 #ifdef SUPPORT_PC88_HMB20
200         pc88event->set_context_sound(pc88opm);
201 #endif
202 #ifdef SUPPORT_PC88_PCG8100
203         pc88event->set_context_sound(pc88pcm0);
204         pc88event->set_context_sound(pc88pcm1);
205         pc88event->set_context_sound(pc88pcm2);
206 #endif
207         pc88event->set_context_sound(pc88noise_seek);
208         pc88event->set_context_sound(pc88noise_head_down);
209         pc88event->set_context_sound(pc88noise_head_up);
210         
211         pc88->set_context_cpu(pc88cpu);
212         pc88->set_context_opn(pc88opn);
213 #ifdef SUPPORT_PC88_SB2
214         pc88->set_context_sb2(pc88sb2);
215 #endif
216         pc88->set_context_pcm(pc88pcm);
217         pc88->set_context_pio(pc88pio);
218         pc88->set_context_prn(pc88prn);
219         pc88->set_context_rtc(pc88rtc);
220         pc88->set_context_sio(pc88sio);
221 #ifdef SUPPORT_PC88_CDROM
222         pc88->set_context_scsi_host(pc88scsi_host);
223         pc88->set_context_scsi_cdrom(pc88scsi_cdrom);
224 #endif
225 #ifdef SUPPORT_PC88_HMB20
226         pc88->set_context_opm(pc88opm);
227 #endif
228 #ifdef SUPPORT_PC88_PCG8100
229         pc88->set_context_pcg_pit(pc88pit);
230         pc88->set_context_pcg_pcm0(pc88pcm0);
231         pc88->set_context_pcg_pcm1(pc88pcm1);
232         pc88->set_context_pcg_pcm2(pc88pcm2);
233 #endif
234         pc88cpu->set_context_mem(pc88);
235         pc88cpu->set_context_io(pc88);
236         pc88cpu->set_context_intr(pc88);
237 #ifdef USE_DEBUGGER
238         pc88cpu->set_context_debugger(new DEBUGGER(this, emu));
239 #endif
240         pc88opn->set_context_irq(pc88, SIG_PC88_SOUND_IRQ, 1);
241 #ifdef SUPPORT_PC88_SB2
242         if(pc88sb2 != NULL) {
243                 pc88sb2->set_context_irq(pc88, SIG_PC88_SB2_IRQ, 1);
244         }
245 #endif
246         pc88sio->set_context_rxrdy(pc88, SIG_PC88_USART_IRQ, 1);
247         pc88sio->set_context_out(pc88, SIG_PC88_USART_OUT);
248         
249         pc88sub->set_context_cpu(pc88cpu_sub);
250         pc88sub->set_context_fdc(pc88fdc_sub);
251         pc88sub->set_context_pio(pc88pio_sub);
252         pc88pio->set_context_port_a(pc88pio_sub, SIG_I8255_PORT_B, 0xff, 0);
253         pc88pio->set_context_port_b(pc88pio_sub, SIG_I8255_PORT_A, 0xff, 0);
254         pc88pio->set_context_port_c(pc88pio_sub, SIG_I8255_PORT_C, 0x0f, 4);
255         pc88pio->set_context_port_c(pc88pio_sub, SIG_I8255_PORT_C, 0xf0, -4);
256         pc88pio->clear_ports_by_cmdreg = true;
257         pc88pio_sub->set_context_port_a(pc88pio, SIG_I8255_PORT_B, 0xff, 0);
258         pc88pio_sub->set_context_port_b(pc88pio, SIG_I8255_PORT_A, 0xff, 0);
259         pc88pio_sub->set_context_port_c(pc88pio, SIG_I8255_PORT_C, 0x0f, 4);
260         pc88pio_sub->set_context_port_c(pc88pio, SIG_I8255_PORT_C, 0xf0, -4);
261         pc88pio_sub->clear_ports_by_cmdreg = true;
262         pc88fdc_sub->set_context_irq(pc88cpu_sub, SIG_CPU_IRQ, 1);
263         pc88fdc_sub->set_context_noise_seek(pc88noise_seek);
264         pc88fdc_sub->set_context_noise_head_down(pc88noise_head_down);
265         pc88fdc_sub->set_context_noise_head_up(pc88noise_head_up);
266         pc88cpu_sub->set_context_mem(pc88sub);
267         pc88cpu_sub->set_context_io(pc88sub);
268         pc88cpu_sub->set_context_intr(pc88sub);
269 #ifdef USE_DEBUGGER
270         pc88cpu_sub->set_context_debugger(new DEBUGGER(this, emu));
271 #endif
272         
273 #ifdef SUPPORT_PC88_CDROM
274         pc88scsi_cdrom->scsi_id = 0;
275         pc88scsi_cdrom->set_context_interface(pc88scsi_host);
276         pc88scsi_host->set_context_target(pc88scsi_cdrom);
277         pc88scsi_host->set_context_drq(pc88, SIG_PC88_SCSI_DRQ, 1);
278 #endif
279 #ifdef SUPPORT_PC88_PCG8100
280         pc88pit->set_context_ch0(pc88pcm0, SIG_PCM1BIT_SIGNAL, 1);
281         pc88pit->set_context_ch1(pc88pcm1, SIG_PCM1BIT_SIGNAL, 1);
282         pc88pit->set_context_ch2(pc88pcm2, SIG_PCM1BIT_SIGNAL, 1);
283         pc88pit->set_constant_clock(0, 3993624);
284         pc88pit->set_constant_clock(1, 3993624);
285         pc88pit->set_constant_clock(2, 3993624);
286 #endif
287         
288         // initialize all devices
289         for(DEVICE* device = first_device; device; device = device->next_device) {
290                 device->initialize();
291         }
292 }
293
294 VM::~VM()
295 {
296         // delete all devices
297         for(DEVICE* device = first_device; device;) {
298                 DEVICE *next_device = device->next_device;
299                 device->release();
300                 delete device;
301                 device = next_device;
302         }
303 }
304
305 DEVICE* VM::get_device(int id)
306 {
307         for(DEVICE* device = first_device; device; device = device->next_device) {
308                 if(device->this_device_id == id) {
309                         return device;
310                 }
311         }
312         return NULL;
313 }
314
315 // ----------------------------------------------------------------------------
316 // drive virtual machine
317 // ----------------------------------------------------------------------------
318
319 void VM::reset()
320 {
321         // reset all devices
322         for(DEVICE* device = first_device; device; device = device->next_device) {
323                 device->reset();
324         }
325         for(DEVICE* device = first_device; device; device = device->next_device) {
326                 device->reset();
327         }
328         
329         // initial device settings
330         pc88opn->set_reg(0x29, 3); // for Misty Blue
331         pc88pio->write_signal(SIG_I8255_PORT_C, 0, 0xff);
332         pc88pio_sub->write_signal(SIG_I8255_PORT_C, 0, 0xff);
333 }
334
335 void VM::run()
336 {
337         pc88event->drive();
338 }
339
340 double VM::get_frame_rate()
341 {
342         return pc88event->get_frame_rate();
343 }
344
345 // ----------------------------------------------------------------------------
346 // debugger
347 // ----------------------------------------------------------------------------
348
349 #ifdef USE_DEBUGGER
350 DEVICE *VM::get_cpu(int index)
351 {
352         if(index == 0) {
353                 return pc88cpu;
354         } else if(index == 1) {
355                 return pc88cpu_sub;
356         }
357         return NULL;
358 }
359 #endif
360
361 // ----------------------------------------------------------------------------
362 // draw screen
363 // ----------------------------------------------------------------------------
364
365 void VM::draw_screen()
366 {
367         pc88->draw_screen();
368 }
369
370 // ----------------------------------------------------------------------------
371 // soud manager
372 // ----------------------------------------------------------------------------
373
374 void VM::initialize_sound(int rate, int samples)
375 {
376         // init sound manager
377         pc88event->initialize_sound(rate, samples);
378         
379         // init sound gen
380         if(pc88opn->is_ym2608) {
381                 pc88opn->initialize_sound(rate, 7987248, samples, 0, 0);
382         } else {
383                 pc88opn->initialize_sound(rate, 3993624, samples, 0, 0);
384         }
385 #ifdef SUPPORT_PC88_SB2
386         if(pc88sb2 != NULL) {
387                 if(pc88sb2->is_ym2608) {
388                         pc88sb2->initialize_sound(rate, 7987248, samples, 0, 0);
389                 } else {
390                         pc88sb2->initialize_sound(rate, 3993624, samples, 0, 0);
391                 }
392         }
393 #endif
394         pc88pcm->initialize_sound(rate, 8000);
395 #ifdef SUPPORT_PC88_HMB20
396         pc88opm->initialize_sound(rate, 4000000, samples, 0);
397 #endif
398 #ifdef SUPPORT_PC88_PCG8100
399         pc88pcm0->initialize_sound(rate, 8000);
400         pc88pcm1->initialize_sound(rate, 8000);
401         pc88pcm2->initialize_sound(rate, 8000);
402 #endif
403 }
404
405 uint16_t* VM::create_sound(int* extra_frames)
406 {
407         return pc88event->create_sound(extra_frames);
408 }
409
410 int VM::get_sound_buffer_ptr()
411 {
412         return pc88event->get_sound_buffer_ptr();
413 }
414
415 #ifdef USE_SOUND_VOLUME
416 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
417 {
418         if(ch-- == 0) {
419                 pc88opn->set_volume(0, decibel_l, decibel_r);
420         } else if(ch-- == 0) {
421                 pc88opn->set_volume(1, decibel_l, decibel_r);
422 #ifdef SUPPORT_PC88_OPNA
423         } else if(ch-- == 0) {
424                 pc88opn->set_volume(2, decibel_l, decibel_r);
425         } else if(ch-- == 0) {
426                 pc88opn->set_volume(3, decibel_l, decibel_r);
427 #endif
428 #ifdef SUPPORT_PC88_SB2
429         } else if(ch-- == 0) {
430                 if(pc88sb2 != NULL) {
431                         pc88sb2->set_volume(0, decibel_l, decibel_r);
432                 }
433         } else if(ch-- == 0) {
434                 if(pc88sb2 != NULL) {
435                         pc88sb2->set_volume(1, decibel_l, decibel_r);
436                 }
437 #ifdef SUPPORT_PC88_OPNA
438         } else if(ch-- == 0) {
439                 if(pc88sb2 != NULL) {
440                         pc88sb2->set_volume(2, decibel_l, decibel_r);
441                 }
442         } else if(ch-- == 0) {
443                 if(pc88sb2 != NULL) {
444                         pc88sb2->set_volume(3, decibel_l, decibel_r);
445                 }
446 #endif
447 #endif
448 #ifdef SUPPORT_PC88_CDROM
449         } else if(ch-- == 0) {
450                 pc88scsi_cdrom->set_volume(0, decibel_l, decibel_r);
451 #endif
452 #ifdef SUPPORT_PC88_HMB20
453         } else if(ch-- == 0) {
454                 pc88opm->set_volume(0, decibel_l, decibel_r);
455 #endif
456 #ifdef SUPPORT_PC88_PCG8100
457         } else if(ch-- == 0) {
458                 pc88pcm0->set_volume(0, decibel_l, decibel_r);
459                 pc88pcm1->set_volume(0, decibel_l, decibel_r);
460                 pc88pcm2->set_volume(0, decibel_l, decibel_r);
461 #endif
462         } else if(ch-- == 0) {
463                 pc88pcm->set_volume(0, decibel_l, decibel_r);
464         } else if(ch-- == 0) {
465                 pc88noise_seek->set_volume(0, decibel_l, decibel_r);
466                 pc88noise_head_down->set_volume(0, decibel_l, decibel_r);
467                 pc88noise_head_up->set_volume(0, decibel_l, decibel_r);
468         }
469 }
470 #endif
471
472 // ----------------------------------------------------------------------------
473 // notify key
474 // ----------------------------------------------------------------------------
475
476 void VM::key_down(int code, bool repeat)
477 {
478         pc88->key_down(code, repeat);
479 }
480
481 void VM::key_up(int code)
482 {
483 }
484
485 bool VM::get_caps_locked()
486 {
487         return pc88->get_caps_locked();
488 }
489
490 bool VM::get_kana_locked()
491 {
492         return pc88->get_kana_locked();
493 }
494
495 // ----------------------------------------------------------------------------
496 // user interface
497 // ----------------------------------------------------------------------------
498
499 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
500 {
501         pc88fdc_sub->open_disk(drv, file_path, bank);
502 }
503
504 void VM::close_floppy_disk(int drv)
505 {
506         pc88fdc_sub->close_disk(drv);
507 }
508
509 bool VM::is_floppy_disk_inserted(int drv)
510 {
511         return pc88fdc_sub->is_disk_inserted(drv);
512 }
513
514 void VM::is_floppy_disk_protected(int drv, bool value)
515 {
516         pc88fdc_sub->is_disk_protected(drv, value);
517 }
518
519 bool VM::is_floppy_disk_protected(int drv)
520 {
521         return pc88fdc_sub->is_disk_protected(drv);
522 }
523
524 uint32_t VM::is_floppy_disk_accessed()
525 {
526         return pc88fdc_sub->read_signal(0);
527 }
528
529 void VM::play_tape(int drv, const _TCHAR* file_path)
530 {
531         pc88->play_tape(file_path);
532 }
533
534 void VM::rec_tape(int drv, const _TCHAR* file_path)
535 {
536         pc88->rec_tape(file_path);
537 }
538
539 void VM::close_tape(int drv)
540 {
541         pc88->close_tape();
542 }
543
544 bool VM::is_tape_inserted(int drv)
545 {
546         return pc88->is_tape_inserted();
547 }
548
549 #ifdef SUPPORT_PC88_CDROM
550 void VM::open_compact_disc(int drv, const _TCHAR* file_path)
551 {
552         pc88scsi_cdrom->open(file_path);
553 }
554
555 void VM::close_compact_disc(int drv)
556 {
557         pc88scsi_cdrom->close();
558 }
559
560 bool VM::is_compact_disc_inserted(int drv)
561 {
562         return pc88scsi_cdrom->mounted();
563 }
564
565 uint32_t VM::is_compact_disc_accessed()
566 {
567         return pc88scsi_cdrom->accessed();
568 }
569 #endif
570
571 bool VM::is_frame_skippable()
572 {
573 //      return event->is_frame_skippable();
574         return pc88->is_frame_skippable();
575 }
576
577 void VM::update_config()
578 {
579         if(boot_mode != config.boot_mode) {
580                 // boot mode is changed !!!
581                 boot_mode = config.boot_mode;
582                 reset();
583         } else {
584                 for(DEVICE* device = first_device; device; device = device->next_device) {
585                         device->update_config();
586                 }
587         }
588 }
589
590 #define STATE_VERSION   10
591
592 bool VM::process_state(FILEIO* state_fio, bool loading)
593 {
594         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
595                 return false;
596         }
597         for(DEVICE* device = first_device; device; device = device->next_device) {
598                 // Note: typeid(foo).name is fixed by recent ABI.Not decr. 6.
599                 // const char *name = typeid(*device).name();
600                 //       But, using get_device_name() instead of typeid(foo).name() 20181008 K.O
601                 const char *name = device->get_device_name();
602                 int len = strlen(name);
603                 if(!state_fio->StateCheckInt32(len)) {
604                         return false;
605                 }
606                 if(!state_fio->StateCheckBuffer(name, len, 1)) {
607                         return false;
608                 }
609                 if(!device->process_state(state_fio, loading)) {
610                         if(loading) {
611                                 printf("Data loading Error: DEVID=%d\n", device->this_device_id);
612                         }
613                         return false;
614                 }
615         }
616         // Machine specified.
617         state_fio->StateValue(boot_mode);
618         return true;
619 }
620