OSDN Git Service

[VM][FM7] Add PRINTER ; output to file(s) and Dempa shimbun-sha Joy stick.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / fm7.cpp
1
2 /*
3  * FM7 -> VM
4  * (C) 2015 K.Ohta <whatisthis.sowhat _at_ gmail.com>
5  * History:
6  *   Feb 27, 2015 : Initial
7  */
8
9 #include "fm7.h"
10 #include "../../emu.h"
11 #include "../../config.h"
12 #include "../device.h"
13 #include "../event.h"
14 #include "../memory.h"
15 #include "../prnfile.h"
16
17 #ifdef USE_DEBUGGER
18 #include "../debugger.h"
19 #endif
20 #if defined(SUPPORT_DUMMY_DEVICE_LED)
21 #include "../dummydevice.h"
22 #else
23 #define SIG_DUMMYDEVICE_BIT0 0
24 #define SIG_DUMMYDEVICE_BIT1 1
25 #define SIG_DUMMYDEVICE_BIT2 2
26 #endif
27
28 #include "../datarec.h"
29 #include "../disk.h"
30
31 #include "../mc6809.h"
32 #include "../z80.h"
33 #include "../mb8877.h"
34
35 #include "../pcm1bit.h"
36 #include "../ym2203.h"
37 #if defined(_FM77AV_VARIANTS)
38 #include "mb61vh010.h"
39 #include "../beep.h"
40 #endif
41 #if defined(HAS_DMA)
42 #include "hd6844.h"
43 #endif
44
45 #include "./fm7_mainio.h"
46 #include "./fm7_mainmem.h"
47 #include "./fm7_display.h"
48 #include "./fm7_keyboard.h"
49 #include "./joystick.h"
50
51 #include "./kanjirom.h"
52
53 VM::VM(EMU* parent_emu): emu(parent_emu)
54 {
55         
56         first_device = last_device = NULL;
57         connect_opn = false;
58         connect_whg = false;
59         connect_thg = false;
60 #if defined(_FM77AV_VARIANTS)
61         opn[0] = opn[1] = opn[2] = NULL; 
62 #else   
63         opn[0] = opn[1] = opn[2] = psg = NULL; 
64 #endif
65         dummy = new DEVICE(this, emu);  // must be 1st device
66         event = new EVENT(this, emu);   // must be 2nd device
67         
68         dummycpu = new DEVICE(this, emu);
69         maincpu = new MC6809(this, emu);
70         subcpu = new MC6809(this, emu);
71 #ifdef WITH_Z80
72         z80cpu = new Z80(this, emu);
73 #endif
74         // basic devices
75         kanjiclass1 = new KANJIROM(this, emu, false);
76 #ifdef CAPABLE_KANJI_CLASS2
77         kanjiclass2 = new KANJIROM(this, emu, true);
78 #endif
79         joystick  = new JOYSTICK(this, emu);
80         
81         // I/Os
82         drec = new DATAREC(this, emu);
83         pcm1bit = new PCM1BIT(this, emu);
84         fdc  = new MB8877(this, emu);
85 #if defined(HAS_DMA)
86         dmac = new HD6844(this, emu);
87 #endif   
88         opn[0] = new YM2203(this, emu); // OPN
89         opn[1] = new YM2203(this, emu); // WHG
90         opn[2] = new YM2203(this, emu); // THG
91    
92 #if !defined(_FM77AV_VARIANTS)
93         psg = new YM2203(this, emu);
94 #endif
95 #if defined(_FM77AV_VARIANTS)
96         alu = new MB61VH010(this, emu);
97         keyboard_beep = new BEEP(this, emu);
98 #endif  
99         keyboard = new KEYBOARD(this, emu);
100         display = new DISPLAY(this, emu);       
101         printer = new PRNFILE(this, emu);
102         mainio  = new FM7_MAINIO(this, emu);
103         mainmem = new FM7_MAINMEM(this, emu);
104
105 #if defined(SUPPORT_DUMMY_DEVICE_LED)
106         led_terminate = new DUMMYDEVICE(this, emu);
107 #else
108         led_terminate = new DEVICE(this, emu);
109 #endif
110         //maincpu = new MC6809(this, emu);
111         //subcpu = new MC6809(this, emu);
112 #ifdef WITH_Z80
113         //z80cpu = new Z80(this, emu);
114 #endif
115         // MEMORIES must set before initialize().
116         maincpu->set_context_mem(mainmem);
117         subcpu->set_context_mem(display);
118 #ifdef WITH_Z80
119         z80cpu->set_context_mem(mainmem);
120 #endif
121 #ifdef USE_DEBUGGER
122         maincpu->set_context_debugger(new DEBUGGER(this, emu));
123         subcpu->set_context_debugger(new DEBUGGER(this, emu));
124 # ifdef WITH_Z80
125         z80cpu->set_context_debugger(new DEBUGGER(this, emu));
126 # endif
127 #endif
128         connect_bus();
129         initialize();
130 }
131
132 VM::~VM()
133 {
134         // delete all devices
135         for(DEVICE* device = first_device; device;) {
136                 DEVICE *next_device = device->next_device;
137                 device->release();
138                 delete device;
139                 device = next_device;
140         }
141 }
142
143 DEVICE* VM::get_device(int id)
144 {
145         for(DEVICE* device = first_device; device; device = device->next_device) {
146                 if(device->this_device_id == id) {
147                         return device;
148                 }
149         }
150         return NULL;
151 }
152
153
154 void VM::initialize(void)
155 {
156         clock_low = false;
157         
158 }
159
160
161 void VM::connect_bus(void)
162 {
163         uint32 mainclock;
164         uint32 subclock;
165
166         /*
167          * CLASS CONSTRUCTION
168          *
169          * VM 
170          *  |-> MAINCPU -> MAINMEM -> MAINIO -> MAIN DEVICES
171          *  |             |        |      
172          *  | -> SUBCPU  -> SUBMEM  -> SUBIO -> SUB DEVICES
173          *  | -> DISPLAY
174          *  | -> KEYBOARD
175          *
176          *  MAINMEM can access SUBMEM/IO, when SUBCPU is halted.
177          *  MAINMEM and SUBMEM can access DISPLAY and KEYBOARD with exclusive.
178          *  MAINCPU can access MAINMEM.
179          *  SUBCPU  can access SUBMEM.
180          *  DISPLAY : R/W from MAINCPU and SUBCPU.
181          *  KEYBOARD : R/W
182          *
183          */
184         event->set_frames_per_sec(FRAMES_PER_SEC);
185         event->set_lines_per_frame(LINES_PER_FRAME);
186         event->set_context_cpu(dummycpu, (CPU_CLOCKS * 3) / 8); // MAYBE FIX With eFM77AV40/20.
187         //event->set_context_cpu(dummycpu, (int)(4.9152 * 1000.0 * 1000.0 / 4.0));
188         
189 #if defined(_FM8)
190         mainclock = MAINCLOCK_SLOW;
191         subclock = SUBCLOCK_SLOW;
192 #else
193         if(config.cpu_type == 0) {
194                 // 2MHz
195                 subclock = SUBCLOCK_NORMAL;
196                 mainclock = MAINCLOCK_NORMAL;
197         } else {
198                 // 1.2MHz
199                 mainclock = MAINCLOCK_SLOW;
200                 subclock = SUBCLOCK_SLOW;
201         }
202         //if((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) subclock = subclock / 3;
203 #endif
204         event->set_context_cpu(maincpu, mainclock);
205         event->set_context_cpu(subcpu,  subclock);
206    
207 #ifdef WITH_Z80
208         event->set_context_cpu(z80cpu,  4000000);
209         z80cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
210 #endif
211
212         event->set_context_sound(pcm1bit);
213 #if !defined(_FM77AV_VARIANTS)
214         mainio->set_context_psg(psg);
215         event->set_context_sound(psg);
216 #endif
217         event->set_context_sound(opn[0]);
218         event->set_context_sound(opn[1]);
219         event->set_context_sound(opn[2]);
220         event->set_context_sound(drec);
221 #if defined(_FM77AV_VARIANTS)
222         event->set_context_sound(keyboard_beep);
223 #endif
224    
225         event->register_frame_event(display);
226         //event->register_vline_event(display);
227         //event->register_vline_event(mainio);
228    
229         mainio->set_context_maincpu(maincpu);
230         mainio->set_context_subcpu(subcpu);
231         
232         mainio->set_context_display(display);
233         mainio->set_context_kanjirom_class1(kanjiclass1);
234         mainio->set_context_mainmem(mainmem);
235         mainio->set_context_keyboard(keyboard);
236         mainio->set_context_printer(printer);
237    
238 #if defined(CAPABLE_KANJI_CLASS2)
239         mainio->set_context_kanjirom_class2(kanjiclass2);
240 #endif
241
242         keyboard->set_context_break_line(mainio, FM7_MAINIO_PUSH_BREAK, 0xffffffff);
243         keyboard->set_context_int_line(mainio, FM7_MAINIO_KEYBOARDIRQ, 0xffffffff);
244         keyboard->set_context_int_line(display, SIG_FM7_SUB_KEY_FIRQ, 0xffffffff);
245 #if defined(_FM77AV_VARIANTS)
246         keyboard->set_context_beep(keyboard_beep);
247 #endif  
248         keyboard->set_context_rxrdy(display, SIG_FM7KEY_RXRDY, 0x01);
249         keyboard->set_context_key_ack(display, SIG_FM7KEY_ACK, 0x01);
250         keyboard->set_context_ins_led( led_terminate, SIG_DUMMYDEVICE_BIT0, 0xffffffff);
251         keyboard->set_context_caps_led(led_terminate, SIG_DUMMYDEVICE_BIT1, 0xffffffff);
252         keyboard->set_context_kana_led(led_terminate, SIG_DUMMYDEVICE_BIT2, 0xffffffff);
253    
254         drec->set_context_ear(mainio, FM7_MAINIO_CMT_RECV, 0xffffffff);
255         //drec->set_context_remote(mainio, FM7_MAINIO_CMT_REMOTE, 0xffffffff);
256         mainio->set_context_datarec(drec);
257         mainmem->set_context_mainio(mainio);
258         mainmem->set_context_display(display);
259         mainmem->set_context_maincpu(maincpu);
260 #if defined(CAPABLE_DICTROM)
261         mainmem->set_context_kanjirom_class1(kanjiclass1);
262 #endif  
263         display->set_context_mainio(mainio);
264         display->set_context_subcpu(subcpu);
265         display->set_context_keyboard(keyboard);
266         subcpu->set_context_bus_halt(display, SIG_FM7_SUB_HALT, 0xffffffff);
267         subcpu->set_context_bus_halt(mainmem, SIG_FM7_SUB_HALT, 0xffffffff);
268
269         display->set_context_kanjiclass1(kanjiclass1);
270 #if defined(CAPABLE_KANJI_CLASS2)
271         display->set_context_kanjiclass2(kanjiclass2);
272 #endif   
273 #if defined(_FM77AV_VARIANTS)
274         display->set_context_alu(alu);
275         alu->set_context_memory(display);
276 #endif  
277         // Palette, VSYNC, HSYNC, Multi-page, display mode. 
278         mainio->set_context_display(display);
279         
280         //FDC
281         mainio->set_context_fdc(fdc);
282         fdc->set_context_irq(mainio, FM7_MAINIO_FDC_IRQ, 0x1);
283         fdc->set_context_drq(mainio, FM7_MAINIO_FDC_DRQ, 0x1);
284         // SOUND
285         mainio->set_context_beep(pcm1bit);
286         
287         opn[0]->set_context_irq(mainio, FM7_MAINIO_OPN_IRQ, 0xffffffff);
288         mainio->set_context_opn(opn[0], 0);
289         //joystick->set_context_opn(opn[0]);
290         mainio->set_context_joystick(joystick);
291         opn[0]->set_context_port_b(joystick, FM7_JOYSTICK_MOUSE_STROBE, 0xff, 0);
292         
293         opn[1]->set_context_irq(mainio, FM7_MAINIO_WHG_IRQ, 0xffffffff);
294         mainio->set_context_opn(opn[1], 1);
295         opn[2]->set_context_irq(mainio, FM7_MAINIO_THG_IRQ, 0xffffffff);
296         mainio->set_context_opn(opn[2], 2);
297    
298         subcpu->set_context_bus_halt(display, SIG_FM7_SUB_HALT, 0xffffffff);
299         subcpu->set_context_bus_clr(display, SIG_FM7_SUB_USE_CLR, 0x0000000f);
300    
301         event->register_frame_event(joystick);
302 #if defined(HAS_DMA)
303         dmac->set_context_src(fdc, 0);
304         dmac->set_context_dst(mainmem, 0);
305         dmac->set_context_int_line(mainio, 0, FM7_MAINIO_DMA_INT, 0xffffffff);
306         dmac->set_context_drq_line(maincpu, 1, SIG_CPU_BUSREQ, 0xffffffff);
307         mainio->set_context_dmac(dmac);
308 #endif
309         for(DEVICE* device = first_device; device; device = device->next_device) {
310                 device->initialize();
311         }
312         for(int i = 0; i < 2; i++) {
313 #if defined(_FM77AV20) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
314                 fdc->set_drive_type(i, DRIVE_TYPE_2DD);
315 #else
316                 fdc->set_drive_type(i, DRIVE_TYPE_2D);
317 #endif
318 #if defined(_FM77AV_VARIANTS)
319                 fdc->set_drive_rpm(i, 360);
320 #else           
321                 fdc->set_drive_rpm(i, 360);
322 #endif          
323                 fdc->set_drive_mfm(i, true);
324         }
325 #if defined(_FM77) || defined(_FM77L4)
326         for(int i = 2; i < 4; i++) {
327                 fdc->set_drive_type(i, DRIVE_TYPE_2HD);
328                 fdc->set_drive_rpm(i, 360);
329                 fdc->set_drive_mfm(i, true);
330         }
331 #endif
332         
333 }  
334
335 void VM::update_config()
336 {
337         uint32 vol1, vol2, tmpv;
338         int ii, i_limit;
339
340 #if defined(SIG_YM2203_LVOLUME) && defined(SIG_YM2203_RVOLUME)
341 # if defined(USE_MULTIPLE_SOUNDCARDS)
342         i_limit = USE_MULTIPLE_SOUNDCARDS - 1;
343 # else
344 #  if !defined(_FM77AV_VARIANTS) && !defined(_FM8)
345         i_limit = 4;
346 #  elif defined(_FM8)
347         i_limit = 1; // PSG Only
348 #  else
349         i_limit = 3;
350 #  endif
351 # endif
352
353         for(ii = 0; ii < i_limit; ii++) {
354                 if(config.multiple_speakers) { //
355 # if defined(USE_MULTIPLE_SOUNDCARDS)
356                         vol1 = (config.sound_device_level[ii] + 32768) >> 8;
357 # else
358                         vol1 = 256;
359 # endif //
360
361                         vol2 = vol1 >> 2;
362                 } else {
363 # if defined(USE_MULTIPLE_SOUNDCARDS)
364                         vol1 = vol2 = (config.sound_device_level[ii] + 32768) >> 8;
365 # else
366                         vol1 = vol2 = 256;
367 # endif
368                 }
369                 switch(ii) {
370                 case 0: // OPN
371                         break;
372                 case 1: // WHG
373                 case 3: // PSG
374                         tmpv = vol1;
375                         vol1 = vol2;
376                         vol2 = tmpv;
377                         break;
378                 case 2: // THG
379                         vol2 = vol1;
380                         break;
381                 default:
382                         break;
383                 }
384                 if(ii < i_limit) {
385                         opn[ii]->write_signal(SIG_YM2203_LVOLUME, vol1, 0xffffffff); // OPN: LEFT
386                         opn[ii]->write_signal(SIG_YM2203_RVOLUME, vol2, 0xffffffff); // OPN: RIGHT
387                 }
388         }
389 #endif   
390 #if defined(USE_MULTIPLE_SOUNDCARDS) && defined(DATAREC_SOUND)
391         drec->write_signal(SIG_DATAREC_VOLUME, (config.sound_device_level[USE_MULTIPLE_SOUNDCARDS - 1] + 32768) >> 3, 0xffffffff); 
392 #endif
393         for(DEVICE* device = first_device; device; device = device->next_device) {
394                 device->update_config();
395         }
396         //update_dipswitch();
397 }
398
399 void VM::reset()
400 {
401         // reset all devices
402         for(DEVICE* device = first_device; device; device = device->next_device) {
403                 device->reset();
404         }
405         //subcpu->reset();
406         //maincpu->reset();
407         
408         opn[0]->SetReg(0x2e, 0);        // set prescaler
409         opn[1]->SetReg(0x2e, 0);        // set prescaler
410         opn[2]->SetReg(0x2e, 0);        // set prescaler
411
412         // Init OPN/PSG.
413         // Parameters from XM7.
414         opn[0]->write_signal(SIG_YM2203_MUTE, 0x00, 0x01); // Okay?
415         opn[1]->write_signal(SIG_YM2203_MUTE, 0x00, 0x01); // Okay?
416         opn[2]->write_signal(SIG_YM2203_MUTE, 0x00, 0x01); // Okay?
417
418 #if !defined(_FM77AV_VARIANTS)
419         psg->SetReg(0x27, 0); // stop timer
420         psg->SetReg(0x2e, 0);   // set prescaler
421         psg->write_signal(SIG_YM2203_MUTE, 0x00, 0x01); // Okay?
422 #endif  
423 }
424
425 void VM::special_reset()
426 {
427         // BREAK + RESET
428         mainio->write_signal(FM7_MAINIO_PUSH_BREAK, 1, 1);
429         mainio->reset();
430         mainmem->reset();
431         
432 #if defined(FM77AV_VARIANTS)    
433         mainio->write_signal(FM7_MAINIO_HOT_RESET, 1, 1);
434 #endif  
435         display->reset();
436         subcpu->reset();
437         mainio->write_signal(FM7_MAINIO_PUSH_BREAK, 1, 1);
438         maincpu->reset();
439         event->register_event(mainio, EVENT_UP_BREAK, 10000.0 * 1000.0, false, NULL);
440 }
441
442 void VM::run()
443 {
444         event->drive();
445 }
446
447 double VM::frame_rate()
448 {
449         return event->frame_rate();
450 }
451
452 #if defined(SUPPORT_DUMMY_DEVICE_LED)
453 uint32 VM::get_led_status()
454 {
455         return led_terminate->read_signal(SIG_DUMMYDEVICE_READWRITE);
456 }
457 #endif // SUPPORT_DUMMY_DEVICE_LED
458
459
460 // ----------------------------------------------------------------------------
461 // debugger
462 // ----------------------------------------------------------------------------
463
464 #ifdef USE_DEBUGGER
465 DEVICE *VM::get_cpu(int index)
466 {
467         if(index == 0) {
468                 return maincpu;
469         } else if(index == 1) {
470                 return subcpu;
471         }
472 #if defined(_WITH_Z80)
473         else if(index == 2) {
474                 return z80cpu;
475         }
476 #endif
477         return NULL;
478 }
479 #endif
480
481 // ----------------------------------------------------------------------------
482 // draw screen
483 // ----------------------------------------------------------------------------
484
485 void VM::draw_screen()
486 {
487         display->draw_screen();
488 }
489
490 int VM::access_lamp()
491 {
492         uint32 status = fdc->read_signal(0);
493         return (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0;
494 }
495
496 void VM::initialize_sound(int rate, int samples)
497 {
498         // init sound manager
499         event->initialize_sound(rate, samples);
500         // init sound gen
501         opn[0]->init(rate, (int)(4.9152 * 1000.0 * 1000.0 / 4.0), samples, 0, 0);
502         opn[1]->init(rate, (int)(4.9152 * 1000.0 * 1000.0 / 4.0), samples, 0, 0);
503         opn[2]->init(rate, (int)(4.9152 * 1000.0 * 1000.0 / 4.0), samples, 0, 0);
504 #if !defined(_FM77AV_VARIANTS)   
505         psg->init(rate, (int)(4.9152 * 1000.0 * 1000.0 / 4.0), samples, 0, 0);
506 #endif
507 #if defined(_FM77AV_VARIANTS)
508         keyboard_beep->init(rate, 2400.0, 512);
509 #endif
510         pcm1bit->init(rate, 2000);
511         //drec->init_pcm(rate, 0);
512 }
513
514 uint16* VM::create_sound(int* extra_frames)
515 {
516         uint16* p = event->create_sound(extra_frames);
517         return p;
518 }
519
520 int VM::sound_buffer_ptr()
521 {
522         int pos = event->sound_buffer_ptr();
523         return pos; 
524 }
525
526 // ----------------------------------------------------------------------------
527 // notify key
528 // ----------------------------------------------------------------------------
529
530 void VM::key_down(int code, bool repeat)
531 {
532         if(!repeat) {
533                 keyboard->key_down(code);
534         }
535 }
536
537 void VM::key_up(int code)
538 {
539         keyboard->key_up(code);
540 }
541
542 // ----------------------------------------------------------------------------
543 // user interface
544 // ----------------------------------------------------------------------------
545
546 void VM::open_disk(int drv, const _TCHAR* file_path, int bank)
547 {
548         fdc->open_disk(drv, file_path, bank);
549 }
550
551 void VM::close_disk(int drv)
552 {
553         fdc->close_disk(drv);
554 }
555
556 bool VM::disk_inserted(int drv)
557 {
558         return fdc->disk_inserted(drv);
559 }
560
561 void VM::set_disk_protected(int drv, bool value)
562 {
563         fdc->set_disk_protected(drv, value);
564 }
565
566 bool VM::get_disk_protected(int drv)
567 {
568         return fdc->get_disk_protected(drv);
569 }
570
571 void VM::play_tape(const _TCHAR* file_path)
572 {
573         drec->play_tape(file_path);
574 }
575
576 void VM::rec_tape(const _TCHAR* file_path)
577 {
578         drec->rec_tape(file_path);
579 }
580
581 void VM::close_tape()
582 {
583         drec->close_tape();
584 }
585
586 bool VM::tape_inserted()
587 {
588         return drec->tape_inserted();
589 }
590
591 bool VM::tape_playing()
592 {
593         return drec->tape_playing();
594 }
595
596 bool VM::tape_recording()
597 {
598         return drec->tape_recording();
599 }
600
601 int VM::tape_position()
602 {
603         return drec->tape_position();
604 }
605
606 void VM::push_play()
607 {
608         drec->set_ff_rew(0);
609         drec->set_remote(true);
610 }
611
612
613 void VM::push_stop()
614 {
615         drec->set_remote(false);
616 }
617
618 void VM::push_fast_forward()
619 {
620         drec->set_ff_rew(1);
621         drec->set_remote(true);
622 }
623
624 void VM::push_fast_rewind()
625 {
626         drec->set_ff_rew(-1);
627         drec->set_remote(true);
628 }
629
630 void VM::push_apss_forward()
631 {
632         drec->do_apss(1);
633 }
634
635 void VM::push_apss_rewind()
636 {
637         drec->do_apss(-1);
638 }
639
640 bool VM::now_skip()
641 {
642         return event->now_skip();
643 }
644
645 void VM::update_dipswitch()
646 {
647         // bit0         0=High 1=Standard
648         // bit2         0=5"2D 1=5"2HD
649   //    io->set_iovalue_single_r(0x1ff0, (config.monitor_type & 1) | ((config.drive_type & 1) << 2));
650 }
651
652 void VM::set_cpu_clock(DEVICE *cpu, uint32 clocks) {
653         event->set_secondary_cpu_clock(cpu, clocks);
654 }
655
656 #define STATE_VERSION   1
657
658 void VM::save_state(FILEIO* state_fio)
659 {
660         state_fio->FputUint32_BE(STATE_VERSION);
661         
662         for(DEVICE* device = first_device; device; device = device->next_device) {
663                 device->save_state(state_fio);
664         }
665         { // V1
666                 state_fio->FputUint32_BE(connected_opns);
667                 state_fio->FputBool(connect_opn);
668                 state_fio->FputBool(connect_whg);
669                 state_fio->FputBool(connect_thg);
670                 state_fio->FputBool(clock_low);
671         }
672 }
673
674 bool VM::load_state(FILEIO* state_fio)
675 {
676         uint32 version = state_fio->FgetUint32_BE();
677         int i = 1;
678         if(version > STATE_VERSION) {
679                 return false;
680         }
681         for(DEVICE* device = first_device; device; device = device->next_device) {
682                 if(!device->load_state(state_fio)) {
683                         printf("Load Error: DEVID=%d\n", device->this_device_id);
684                         return false;
685                 }
686         }
687         if(version >= 1) {// V1 
688                 connected_opns = state_fio->FgetUint32_BE();
689                 connect_opn = state_fio->FgetBool();
690                 connect_whg = state_fio->FgetBool();
691                 connect_thg = state_fio->FgetBool();
692                 clock_low   = state_fio->FgetBool();
693                 if(version == 1) return true;
694         }
695         return false;
696 }
697
698 #ifdef USE_DIG_RESOLUTION
699 void VM::get_screen_resolution(int *w, int *h)
700 {
701         switch(display->get_screen_mode()) {
702         case DISPLAY_MODE_8_200L:
703         case DISPLAY_MODE_8_200L_TEXT:
704                 *w = 640;
705                 *h = 200;
706                 break;
707         case DISPLAY_MODE_8_400L:
708         case DISPLAY_MODE_8_400L_TEXT:
709                 *w = 640;
710                 *h = 400;
711                 break;
712         case DISPLAY_MODE_4096:
713         case DISPLAY_MODE_256k:
714                 *w = 320;
715                 *h = 200;
716                 break;
717         default:
718                 *w = 640;
719                 *h = 200;
720                 break;
721         }
722 }
723 #endif
724
725 bool VM::screen_changed()
726 {
727         bool f = true;
728 #if defined(USE_MINIMUM_RENDERING)
729         f = display->screen_update();
730         display->reset_screen_update();
731 #endif  
732         return f;
733 }