OSDN Git Service

[VM][FM7] Remove DUMMY CPU.Reduce host-cpu usage a lot.Related to commit a4e1a7cfef59...
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / fm7.cpp
1 /*
2  * FM7 -> VM
3  * (C) 2015 K.Ohta <whatisthis.sowhat _at_ gmail.com>
4  * History:
5  *   Feb 27, 2015 : Initial
6  */
7
8 #include "fm7.h"
9 #include "../../emu.h"
10 #include "../../config.h"
11 #include "../device.h"
12 #include "../event.h"
13 #include "../memory.h"
14 #include "../prnfile.h"
15
16 #ifdef USE_DEBUGGER
17 #include "../debugger.h"
18 #endif
19
20 #include "../datarec.h"
21 #include "../disk.h"
22
23 #include "../mc6809.h"
24 #include "../z80.h"
25 #include "../mb8877.h"
26 #include "../noise.h"
27
28 #include "../pcm1bit.h"
29 #include "../ym2203.h"
30 #include "../ay_3_891x.h"
31 #include "../and.h"
32 #include "../or.h"
33 #include "../i8251.h"
34
35 #if defined(_FM77AV_VARIANTS)
36 #include "mb61vh010.h"
37 #include "../beep.h"
38 #endif
39 #if defined(HAS_DMA)
40 #include "hd6844.h"
41 #endif
42 #if defined(_FM8)
43 #include "./bubblecasette.h"
44 #endif
45 #if defined(_FM8)
46 #include "./fm8_mainio.h"
47 #else
48 #include "./fm7_mainio.h"
49 #endif
50 #include "./fm7_mainmem.h"
51 #include "./fm7_display.h"
52 #include "./fm7_keyboard.h"
53 #include "./joystick.h"
54
55 #include "./kanjirom.h"
56 #if defined(CAPABLE_JCOMMCARD)
57 #include "./jcommcard.h"
58 #endif
59
60 VM::VM(EMU* parent_emu): emu(parent_emu)
61 {
62         
63         first_device = last_device = NULL;
64 #if defined(_FM8)
65         psg = NULL;
66 #else   
67 # if defined(_FM77AV_VARIANTS)
68         opn[0] = opn[1] = opn[2] = NULL;
69 # else   
70         opn[0] = opn[1] = opn[2] = NULL;
71         psg = NULL; 
72 # endif
73 #endif
74         for(int i = 0; i < 3; i++) uart[i] = NULL;
75         
76         dummy = new DEVICE(this, emu);  // must be 1st device
77         event = new EVENT(this, emu);   // must be 2nd device
78         
79         maincpu = new MC6809(this, emu);
80         subcpu = new MC6809(this, emu);
81         g_substat_display = new AND(this, emu);
82         g_substat_mainhalt = new AND(this, emu);
83
84         
85 #ifdef WITH_Z80
86         if((config.dipswitch & FM7_DIPSW_Z80CARD_ON) != 0) {
87                 z80cpu = new Z80(this, emu);
88         } else {
89                 z80cpu = NULL;
90         }
91         g_mainstat = new AND(this, emu);
92         g_intr = new OR(this, emu);
93
94         g_intr_irq = new AND(this, emu);
95         g_intr_firq = new AND(this, emu);
96         g_nmi = new AND(this, emu);
97 #endif
98 #if defined(CAPABLE_JCOMMCARD)
99         if((config.dipswitch & FM7_DIPSW_JSUBCARD_ON) != 0) {
100                 jsubcpu = new MC6809(this, emu);
101                 jcommcard = new FM7_JCOMMCARD(this, emu);
102                 g_jsubhalt = new AND(this, emu);
103         } else {
104                 jsubcpu = NULL;
105                 jcommcard = NULL;
106                 g_jsubhalt = NULL;
107         }
108 #endif
109 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV20) || defined(_FM77AV20EX)
110         uart[0] = new I8251(this, emu);
111 # else
112 #  if defined(CAPABLE_JCOMMCARD)
113         if((config.dipswitch & FM7_DIPSW_JSUBCARD_ON) != 0) uart[0] = new I8251(this, emu);
114 #  endif
115         if(((config.dipswitch & FM7_DIPSW_RS232C_ON) != 0) && (uart[0] == NULL)) uart[0] = new I8251(this, emu);
116 # endif
117         if((config.dipswitch & FM7_DIPSW_MODEM_ON) != 0) uart[1] = new I8251(this, emu);
118         if((config.dipswitch & FM7_DIPSW_MIDI_ON) != 0) uart[2] = new I8251(this, emu);
119
120                 
121         // basic devices
122         // I/Os
123 #if defined(HAS_DMA)
124         dmac = new HD6844(this, emu);
125 #endif   
126 #if defined(_FM8)
127 #  if defined(USE_AY_3_8910_AS_PSG)
128         psg = new AY_3_891X(this, emu);
129 #  else
130         psg = new YM2203(this, emu);
131 #  endif
132 #else   
133         opn[0] = new YM2203(this, emu); // OPN
134         opn[1] = new YM2203(this, emu); // WHG
135         opn[2] = new YM2203(this, emu); // THG
136 # if !defined(_FM77AV_VARIANTS)
137 #  if defined(USE_AY_3_8910_AS_PSG)
138         psg = new AY_3_891X(this, emu);
139 #  else
140         psg = new YM2203(this, emu);
141 #  endif
142 # endif 
143 #endif
144 #if defined(_FM8)
145         for(int i = 0; i < 2; i++) bubble_casette[i] = new BUBBLECASETTE(this, emu);
146 #endif
147         drec = NULL;
148         drec = new DATAREC(this, emu);
149         drec->set_context_noise_play(new NOISE(this, emu));
150         drec->set_context_noise_stop(new NOISE(this, emu));
151         drec->set_context_noise_fast(new NOISE(this, emu));
152         pcm1bit = new PCM1BIT(this, emu);
153
154         connect_320kfdc = connect_1Mfdc = false;
155         fdc = NULL;
156 #if defined(_FM8) || defined(_FM7) || defined(_FMNEW7)
157         if(((config.dipswitch & FM7_DIPSW_CONNECT_320KFDC) != 0) ||
158            ((config.dipswitch & FM7_DIPSW_CONNECT_1MFDC) != 0)) {
159 #endif          
160                 fdc = new MB8877(this, emu);
161                 fdc->set_context_noise_seek(new NOISE(this, emu));
162                 fdc->set_context_noise_head_down(new NOISE(this, emu));
163                 fdc->set_context_noise_head_up(new NOISE(this, emu));
164 #if defined(_FM8) || defined(_FM7) || defined(_FMNEW7)
165                 if((config.dipswitch & FM7_DIPSW_CONNECT_320KFDC) != 0) {
166                         connect_320kfdc = true;
167                 }
168                 if((config.dipswitch & FM7_DIPSW_CONNECT_1MFDC) != 0) {
169                         connect_1Mfdc = true;
170                 }
171 #elif defined(_FM77_VARIANTS)
172                 connect_320kfdc = true;
173                 if((config.dipswitch & FM7_DIPSW_CONNECT_1MFDC) != 0) {
174                         connect_1Mfdc = true;
175                 }
176 #else   // AV or later.
177                 connect_320kfdc = true;
178                 // 1MFDD??
179 #endif          
180 #if defined(_FM8) || defined(_FM7) || defined(_FMNEW7)
181         }
182 #endif  
183         joystick  = new JOYSTICK(this, emu);
184         printer = new PRNFILE(this, emu);
185 #if defined(_FM77AV_VARIANTS)
186         alu = new MB61VH010(this, emu);
187         keyboard_beep = new BEEP(this, emu);
188 #endif  
189         keyboard = new KEYBOARD(this, emu);
190         display = new DISPLAY(this, emu);       
191 #if defined(_FM8)
192         mainio  = new FM8_MAINIO(this, emu);
193 #else
194         mainio  = new FM7_MAINIO(this, emu);
195 #endif
196         mainmem = new FM7_MAINMEM(this, emu);
197
198 #if defined(_FM8) || defined(_FM7) || defined(_FMNEW7)
199         if((config.dipswitch & FM7_DIPSW_CONNECT_KANJIROM) != 0) {
200                 kanjiclass1 = new KANJIROM(this, emu, false);
201         } else {
202                 kanjiclass1 = NULL;
203         }
204 #else
205         kanjiclass1 = new KANJIROM(this, emu, false);
206 #endif  
207 #ifdef CAPABLE_KANJI_CLASS2
208         kanjiclass2 = new KANJIROM(this, emu, true);
209 #endif
210
211 # if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
212         g_rs232c_dtr = new AND(this, emu);
213         g_rs232c_dtr->set_mask(SIG_AND_BIT_0);
214         g_rs232c_dtr->set_mask(SIG_AND_BIT_1);
215
216         // DCD
217 #endif
218 #ifdef WITH_Z80
219         g_mainstat->set_mask(SIG_AND_BIT_0);
220         g_mainstat->set_mask(SIG_AND_BIT_1);
221         maincpu->set_context_bus_ba(g_mainstat, SIG_AND_BIT_0, 0xffffffff);
222         maincpu->set_context_bus_bs(g_mainstat, SIG_AND_BIT_1, 0xffffffff);
223         g_mainstat->set_context_out(mainio, FM7_MAINIO_RUN_Z80, 0xffffffff);
224
225         if(z80cpu != NULL) {
226                 z80cpu->set_context_busack(mainio, FM7_MAINIO_RUN_6809, 0xffffffff);
227                 mainio->set_context_z80cpu(z80cpu);
228         }
229 #endif
230 #if defined(_USE_QT)
231         event->set_device_name(_T("EVENT"));
232         dummy->set_device_name(_T("1st Dummy"));
233         
234         maincpu->set_device_name(_T("MAINCPU(MC6809B)"));
235         subcpu->set_device_name(_T("SUBCPU(MC6809B)"));
236 #if defined(CAPABLE_JCOMMCARD)
237         if(jsubcpu != NULL) {
238                 jsubcpu->set_device_name(_T("J.COMM BOARD CPU(MC6809)"));
239         }
240         if(jcommcard != NULL) {
241                 jcommcard->set_device_name(_T("Japanese COMM BOARD"));
242         }
243         if(g_jsubhalt != NULL) {
244                 g_jsubhalt->set_device_name(_T("J.COMM BOARD HALT(MC6809)"));
245         }
246 # ifdef WITH_Z80
247         if(z80cpu != NULL) z80cpu->set_device_name(_T("Z80 CPU BOARD"));
248 # endif
249         if(fdc != NULL) fdc->set_device_name(_T("MB8877 FDC(320KB)"));
250         
251         if(uart[0] != NULL) {
252                 uart[0]->set_device_name(_T("RS-232C BOARD(I8251 SIO)"));
253         }
254 # if defined(CAPABLE_JCOMMCARD)
255         if((config.dipswitch & FM7_DIPSW_JSUBCARD_ON) != 0) {
256                 if(uart[0] != NULL) uart[0]->set_device_name(_T("J.COMM BOARD RS-232C(I8251 SIO)"));
257         }
258 # elif defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
259         if(uart[0] != NULL) uart[0]->set_device_name(_T("RS-232C(I8251 SIO)"));
260 # endif
261                 
262         if(uart[1] != NULL) {
263                 uart[1]->set_device_name(_T("MODEM BOARD(I8251 SIO)"));
264         }
265         if(uart[2] != NULL) {
266                 uart[2]->set_device_name(_T("MIDI BOARD(I8251 SIO)"));
267         }
268                                                 
269         // basic devices
270         // I/Os
271 # if defined(_FM8)
272         psg->set_device_name(_T("AY-3-8910 PSG"));
273 # else  
274         opn[0]->set_device_name(_T("YM2203 OPN"));
275         opn[1]->set_device_name(_T("YM2203 WHG"));
276         opn[2]->set_device_name(_T("YM2203 THG"));
277 #  if !defined(_FM77AV_VARIANTS)
278         psg->set_device_name(_T("AY-3-8910 PSG"));
279 #  endif
280 # endif
281         pcm1bit->set_device_name(_T("BEEP"));
282         printer->set_device_name(_T("PRINTER I/F"));
283 # if defined(_FM77AV_VARIANTS)
284         keyboard_beep->set_device_name(_T("BEEP(KEYBOARD)"));
285 # endif 
286         if(kanjiclass1 != NULL) kanjiclass1->set_device_name(_T("KANJI ROM CLASS1"));
287 # ifdef CAPABLE_KANJI_CLASS2
288         if(kanjiclass2 != NULL) kanjiclass2->set_device_name(_T("KANJI ROM CLASS2"));
289 # endif
290 # if defined(_FM8)
291         bubble_casette[0]->set_device_name(_T("BUBBLE CASETTE #0"));
292         bubble_casette[1]->set_device_name(_T("BUBBLE CASETTE #1"));
293 # endif 
294 #endif
295 # if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
296         g_rs232c_dtr->set_device_name(_T("RS232C DTR(AND)"));
297 #endif
298 #ifdef WITH_Z80
299         g_intr->set_device_name(_T("Z80 INTR(OR)"));
300         g_mainstat->set_device_name(_T("Z80 HALT/RUN(AND)"));
301         g_intr_irq->set_device_name(_T("Z80 IRQ(AND)"));
302         g_intr_firq->set_device_name(_T("Z80 FIRQ(AND)"));
303         g_nmi->set_device_name(_T("Z80 NMI(AND)"));
304 #endif
305         g_substat_display->set_device_name(_T("DISPLAY STATUS(AND)"));
306         g_substat_mainhalt->set_device_name(_T("SUBSYSTEM HALT STATUS(AND)"));
307 #endif  
308         this->connect_bus();
309         
310 }
311
312 VM::~VM()
313 {
314         // delete all devices
315         for(DEVICE* device = first_device; device;) {
316                 DEVICE *next_device = device->next_device;
317                 device->release();
318                 delete device;
319                 device = next_device;
320         }
321 }
322
323 DEVICE* VM::get_device(int id)
324 {
325         for(DEVICE* device = first_device; device; device = device->next_device) {
326                 if(device->this_device_id == id) {
327                         return device;
328                 }
329         }
330         return NULL;
331 }
332
333 void VM::connect_bus(void)
334 {
335         uint32_t mainclock;
336         uint32_t subclock;
337
338         /*
339          * CLASS CONSTRUCTION
340          *
341          * VM 
342          *  |-> MAINCPU -> MAINMEM -> MAINIO -> MAIN DEVICES
343          *  |             |        |      
344          *  | -> SUBCPU  -> SUBMEM  -> SUBIO -> SUB DEVICES
345          *  | -> DISPLAY
346          *  | -> KEYBOARD
347          *
348          *  MAINMEM can access SUBMEM/IO, when SUBCPU is halted.
349          *  MAINMEM and SUBMEM can access DISPLAY and KEYBOARD with exclusive.
350          *  MAINCPU can access MAINMEM.
351          *  SUBCPU  can access SUBMEM.
352          *  DISPLAY : R/W from MAINCPU and SUBCPU.
353          *  KEYBOARD : R/W
354          *
355          */
356         //event->set_frames_per_sec(FRAMES_PER_SEC);
357         event->set_lines_per_frame(LINES_PER_FRAME);
358 #if defined(_FM8)
359         mainclock = MAINCLOCK_SLOW;
360         subclock = SUBCLOCK_SLOW;
361 #else
362         if(config.cpu_type == 0) {
363                 // 2MHz
364                 subclock = SUBCLOCK_NORMAL;
365                 mainclock = MAINCLOCK_NORMAL;
366         } else {
367                 // 1.2MHz
368                 mainclock = MAINCLOCK_SLOW;
369                 subclock = SUBCLOCK_SLOW;
370         }
371         //if((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) subclock = subclock / 3;
372 #endif
373         event->set_context_cpu(maincpu, mainclock);
374         event->set_context_cpu(subcpu,  subclock);      
375    
376 #ifdef WITH_Z80
377         if(z80cpu != NULL) {
378                 event->set_context_cpu(z80cpu,  4000000);
379                 z80cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
380         }
381         maincpu->write_signal(SIG_CPU_HALTREQ, 0, 1);
382
383         g_intr_irq->set_mask(SIG_AND_BIT_0);
384         g_intr_irq->set_mask(SIG_AND_BIT_1);
385         
386         g_intr_firq->set_mask(SIG_AND_BIT_0);
387         g_intr_firq->set_mask(SIG_AND_BIT_1);
388         
389         g_nmi->set_mask(SIG_AND_BIT_0);
390         g_nmi->set_mask(SIG_AND_BIT_1);
391
392         mainio->set_context_irq(g_intr_irq, SIG_AND_BIT_1, 0xffffffff);
393         g_intr_irq->set_context_out(g_intr, SIG_OR_BIT_0, 0xffffffff);
394         
395         mainio->set_context_firq(g_intr_firq, SIG_AND_BIT_1, 0xffffffff);
396         g_intr_firq->set_context_out(g_intr, SIG_OR_BIT_0, 0xffffffff);
397         
398         if(z80cpu != NULL) g_intr->set_context_out(z80cpu, SIG_CPU_IRQ, 0xffffffff);
399
400         mainio->set_context_nmi(g_nmi, SIG_AND_BIT_1, 0xffffffff);
401         if(z80cpu != NULL) g_nmi->set_context_out(z80cpu, SIG_CPU_NMI, 0xffffffff);
402 #endif
403 #if defined(CAPABLE_JCOMMCARD)
404         if((jsubcpu != NULL) && (jcommcard != NULL)) {
405                 event->set_context_cpu(jsubcpu,  JCOMMCARD_CLOCK);
406                 jcommcard->set_context_cpu(jsubcpu);
407                 if(g_jsubhalt != NULL) {
408                         g_jsubhalt->set_mask(SIG_AND_BIT_0);
409                         g_jsubhalt->set_mask(SIG_AND_BIT_1);
410                 
411                         jsubcpu->set_context_bus_ba(g_jsubhalt, SIG_AND_BIT_0, 0xffffffff);
412                         jsubcpu->set_context_bus_bs(g_jsubhalt, SIG_AND_BIT_1, 0xffffffff);
413                         g_jsubhalt->set_context_out(jcommcard, FM7_JCOMMCARD_BUS_HALT, 0xffffffff);
414                         mainio->set_context_jcommcard(jcommcard);
415                 }
416         }
417 #endif
418         event->set_context_sound(pcm1bit);
419 #if defined(_FM8)
420         event->set_context_sound(psg);
421         if(drec != NULL) event->set_context_sound(drec);
422 #else
423         event->set_context_sound(opn[0]);
424         event->set_context_sound(opn[1]);
425         event->set_context_sound(opn[2]);
426 # if !defined(_FM77AV_VARIANTS)
427         event->set_context_sound(psg);
428 # endif
429         event->set_context_sound(drec);
430         if(fdc != NULL) {
431                 event->set_context_sound(fdc->get_context_noise_seek());
432                 event->set_context_sound(fdc->get_context_noise_head_down());
433                 event->set_context_sound(fdc->get_context_noise_head_up());
434         }
435         if(drec != NULL) {
436                 event->set_context_sound(drec->get_context_noise_play());
437                 event->set_context_sound(drec->get_context_noise_stop());
438                 event->set_context_sound(drec->get_context_noise_fast());
439         }
440 # if defined(_FM77AV_VARIANTS)
441         event->set_context_sound(keyboard_beep);
442 # endif
443 #endif   
444 #if !defined(_FM77AV_VARIANTS) && !defined(_FM77L4)
445         event->register_vline_event(display);
446         event->register_frame_event(display);
447 #endif  
448         mainio->set_context_maincpu(maincpu);
449         mainio->set_context_subcpu(subcpu);
450         
451         mainio->set_context_display(display);
452         mainio->set_context_irq(maincpu, SIG_CPU_IRQ, 0xffffffff);
453         mainio->set_context_firq(maincpu, SIG_CPU_FIRQ, 0xffffffff);
454         mainio->set_context_nmi(maincpu, SIG_CPU_NMI, 0xffffffff);
455 #if defined(_FM77AV) || defined(_FM7) || defined(_FMNEW7) || defined(_FM77_VARIANTS)
456         if((config.dipswitch & FM7_DIPSW_RS232C_ON) != 0)       mainio->set_context_uart(0, uart[0]); /* $FD06- : RS232C */
457 #else
458         mainio->set_context_uart(0, uart[0]);
459 #endif
460         mainio->set_context_uart(1, uart[1]); /* $FD40- : MODEM */
461         mainio->set_context_uart(2, uart[2]); /* $FDEA- : MIDI */
462
463 #if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
464         mainio->set_context_rs232c_dtr(g_rs232c_dtr);
465         if(uart[0] != NULL) uart[0]->set_context_dtr(g_rs232c_dtr, SIG_AND_BIT_1, 0xffffffff);
466 #endif
467         if(uart[0] != NULL) {
468                 uart[0]->set_context_rxrdy(mainio, FM7_MAINIO_UART0_RXRDY, 0xffffffff);
469                 uart[0]->set_context_txrdy(mainio, FM7_MAINIO_UART0_TXRDY, 0xffffffff);
470                 uart[0]->set_context_syndet(mainio, FM7_MAINIO_UART0_SYNDET, 0xffffffff);
471         }
472         if(uart[1] != NULL) {
473                 uart[1]->set_context_rxrdy(mainio, FM7_MAINIO_MODEM_RXRDY, 0xffffffff);
474                 uart[1]->set_context_txrdy(mainio, FM7_MAINIO_MODEM_TXRDY, 0xffffffff);
475                 uart[1]->set_context_syndet(mainio, FM7_MAINIO_MODEM_SYNDET, 0xffffffff);
476         }
477         if(uart[2] != NULL) {
478                 uart[2]->set_context_rxrdy(mainio, FM7_MAINIO_MIDI_RXRDY, 0xffffffff);
479                 uart[2]->set_context_txrdy(mainio, FM7_MAINIO_MIDI_TXRDY, 0xffffffff);
480                 uart[2]->set_context_syndet(mainio, FM7_MAINIO_MIDI_SYNDET, 0xffffffff);
481         }
482         
483 #if defined(_FM8) || defined(_FM7) || defined(_FMNEW7)
484         if((config.dipswitch & FM7_DIPSW_CONNECT_KANJIROM) != 0) {
485                 mainio->set_context_kanjirom_class1(kanjiclass1);
486         }
487 #else
488         mainio->set_context_kanjirom_class1(kanjiclass1);
489 #endif  
490         mainio->set_context_mainmem(mainmem);
491         mainio->set_context_keyboard(keyboard);
492         mainio->set_context_printer(printer);
493         mainio->set_context_printer_reset(printer, SIG_PRINTER_RESET, 0xffffffff);
494         mainio->set_context_printer_strobe(printer, SIG_PRINTER_STROBE, 0xffffffff);
495         mainio->set_context_printer_select(printer, SIG_PRINTER_SELECT, 0xffffffff);
496 #if defined(CAPABLE_KANJI_CLASS2)
497         mainio->set_context_kanjirom_class2(kanjiclass2);
498 #endif
499 #if defined(_FM8)
500         for(int i = 0; i < 2; i++) mainio->set_context_bubble(bubble_casette[i], i);
501 #endif  
502         keyboard->set_context_break_line(mainio, FM7_MAINIO_PUSH_BREAK, 0xffffffff);
503         keyboard->set_context_int_line(mainio, FM7_MAINIO_KEYBOARDIRQ, 0xffffffff);
504         keyboard->set_context_int_line(display, SIG_FM7_SUB_KEY_FIRQ, 0xffffffff);
505 #if defined(_FM77AV_VARIANTS)
506         keyboard->set_context_beep(keyboard_beep);
507 #endif  
508         keyboard->set_context_rxrdy(display, SIG_FM7KEY_RXRDY, 0x01);
509         keyboard->set_context_key_ack(display, SIG_FM7KEY_ACK, 0x01);
510    
511         if(drec != NULL) {
512                 drec->set_context_ear(mainio, FM7_MAINIO_CMT_RECV, 0xffffffff);
513                 //drec->set_context_remote(mainio, FM7_MAINIO_CMT_REMOTE, 0xffffffff);
514                 mainio->set_context_datarec(drec);
515         }
516         mainmem->set_context_mainio(mainio);
517         mainmem->set_context_display(display);
518         mainmem->set_context_maincpu(maincpu);
519 #if defined(CAPABLE_DICTROM)
520         mainmem->set_context_kanjirom_class1(kanjiclass1);
521 #endif  
522         display->set_context_mainio(mainio);
523         display->set_context_subcpu(subcpu);
524         display->set_context_keyboard(keyboard);
525
526         mainio->set_context_clock_status(mainmem, FM7_MAINIO_CLOCKMODE, 0xffffffff);
527         mainio->set_context_clock_status(display, SIG_DISPLAY_CLOCK, 0xffffffff);
528
529         g_substat_display->set_mask(SIG_AND_BIT_0);
530         g_substat_display->set_mask(SIG_AND_BIT_1);
531         subcpu->set_context_bus_ba(g_substat_display, SIG_AND_BIT_0, 0xffffffff);
532         subcpu->set_context_bus_bs(g_substat_display, SIG_AND_BIT_1, 0xffffffff);
533         g_substat_display->set_context_out(display, SIG_FM7_SUB_HALT, 0xffffffff);
534
535         g_substat_mainhalt->set_mask(SIG_AND_BIT_0);
536         g_substat_mainhalt->set_mask(SIG_AND_BIT_1);
537         subcpu->set_context_bus_ba(g_substat_mainhalt, SIG_AND_BIT_0, 0xffffffff);
538         subcpu->set_context_bus_bs(g_substat_mainhalt, SIG_AND_BIT_1, 0xffffffff);
539         g_substat_mainhalt->set_context_out(mainmem, SIG_FM7_SUB_HALT, 0xffffffff);
540
541 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
542         display->set_context_kanjiclass1(kanjiclass1);
543 #endif  
544 #if defined(CAPABLE_KANJI_CLASS2)
545         display->set_context_kanjiclass2(kanjiclass2);
546 #endif   
547 #if defined(_FM77AV_VARIANTS)
548         display->set_context_alu(alu);
549         alu->set_context_memory(display);
550         alu->set_direct_access_offset(DISPLAY_VRAM_DIRECT_ACCESS);
551 #endif  
552         // Palette, VSYNC, HSYNC, Multi-page, display mode. 
553         mainio->set_context_display(display);
554 #if defined(_FM8) || (_FM7) || (_FMNEW7)
555         if(connect_320kfdc || connect_1Mfdc) {
556 #endif          
557                 //FDC
558                 fdc->set_context_irq(mainio, FM7_MAINIO_FDC_IRQ, 0x1);
559                 fdc->set_context_drq(mainio, FM7_MAINIO_FDC_DRQ, 0x1);
560                 mainio->set_context_fdc(fdc);
561 #if defined(_FM8) || (_FM7) || (_FMNEW7)
562         }
563 #endif  
564         // SOUND
565         mainio->set_context_beep(pcm1bit);
566 #if defined(_FM8)       
567         mainio->set_context_psg(psg);
568 #else
569 # if !defined(_FM77AV_VARIANTS)
570         mainio->set_context_psg(psg);
571 # endif
572         opn[0]->set_context_irq(mainio, FM7_MAINIO_OPN_IRQ, 0xffffffff);
573         mainio->set_context_opn(opn[0], 0);
574         joystick->set_context_opn(opn[0]);
575         mainio->set_context_joystick(joystick);
576         opn[0]->set_context_port_b(joystick, FM7_JOYSTICK_MOUSE_STROBE, 0xff, 0);
577         
578         opn[1]->set_context_irq(mainio, FM7_MAINIO_WHG_IRQ, 0xffffffff);
579         mainio->set_context_opn(opn[1], 1);
580         opn[2]->set_context_irq(mainio, FM7_MAINIO_THG_IRQ, 0xffffffff);
581         mainio->set_context_opn(opn[2], 2);
582 #endif   
583         subcpu->set_context_bus_clr(display, SIG_FM7_SUB_USE_CLR, 0x0000000f);
584    
585         event->register_frame_event(joystick);
586 #if defined(HAS_DMA)
587         dmac->set_context_src(fdc, 0);
588         dmac->set_context_dst(mainmem, 0);
589         dmac->set_context_int_line(mainio, FM7_MAINIO_DMA_INT, 0xffffffff);
590         dmac->set_context_busreq_line(maincpu, 1, SIG_CPU_BUSREQ, 0xffffffff);
591         mainio->set_context_dmac(dmac);
592 #endif
593         
594         // MEMORIES must set before initialize().
595         maincpu->set_context_mem(mainmem);
596         subcpu->set_context_mem(display);
597 #ifdef WITH_Z80
598         if(z80cpu != NULL) z80cpu->set_context_mem(mainmem);
599 #endif
600 #if defined(CAPABLE_JCOMMCARD)
601         if((jsubcpu != NULL) && (jcommcard != NULL)) {
602                 jsubcpu->set_context_mem(jcommcard);
603         }
604 #endif
605 #ifdef USE_DEBUGGER
606         maincpu->set_context_debugger(new DEBUGGER(this, emu));
607         subcpu->set_context_debugger(new DEBUGGER(this, emu));
608 # ifdef WITH_Z80
609         if(z80cpu != NULL) z80cpu->set_context_debugger(new DEBUGGER(this, emu));
610 # endif
611 # if defined(CAPABLE_JCOMMCARD)
612         if(jsubcpu != NULL) {
613                 jsubcpu->set_context_debugger(new DEBUGGER(this, emu));
614         }
615 # endif
616 #endif
617         for(DEVICE* device = first_device; device; device = device->next_device) {
618                 device->initialize();
619         }
620
621 #if defined(WITH_Z80)
622         g_intr_irq->write_signal(SIG_AND_BIT_0, ((config.dipswitch & FM7_DIPSW_Z80_IRQ_ON) != 0) ? 1 : 0, 1);
623         g_intr_firq->write_signal(SIG_AND_BIT_0, ((config.dipswitch & FM7_DIPSW_Z80_FIRQ_ON) != 0) ? 1 : 0, 1);
624         g_nmi->write_signal(SIG_AND_BIT_0, ((config.dipswitch & FM7_DIPSW_Z80_NMI_ON) != 0) ? 1 : 0, 1);
625 #endif
626         // Disks
627 #if defined(_FM8) || (_FM7) || (_FMNEW7)
628         if(connect_320kfdc) {
629 #endif          
630                 for(int i = 0; i < 4; i++) {
631 #if defined(_FM77AV20) || defined(_FM77AV20EX) || \
632         defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
633                         fdc->set_drive_type(i, DRIVE_TYPE_2DD);
634 #else
635                         fdc->set_drive_type(i, DRIVE_TYPE_2D);
636 #endif
637                         fdc->set_drive_rpm(i, 360);
638                         fdc->set_drive_mfm(i, true);
639                 }
640 #if defined(_FM8) || (_FM7) || (_FMNEW7)
641         }
642 #endif  
643         
644 #if defined(_FM8) || (_FM7) || (_FMNEW7)
645         if(connect_1Mfdc) {
646 #endif
647 // ToDo: Implement another FDC for 1MB (2HD or 8''), this is used by FM-8 to FM-77? Not FM77AV or later? I still know this.
648 //#if defined(_FM77) || defined(_FM77L4)
649 //              for(int i = 0; i < 4; i++) {
650 //                      fdc->set_drive_type(i, DRIVE_TYPE_2HD);
651 //                      fdc->set_drive_rpm(i, 360);
652 //                      fdc->set_drive_mfm(i, true);
653 //              }
654 //#endif
655 #if defined(_FM8) || (_FM7) || (_FMNEW7)
656         }
657 #endif  
658 }  
659
660 void VM::update_config()
661 {
662         for(DEVICE* device = first_device; device; device = device->next_device) {
663                 device->update_config();
664         }
665         update_dipswitch();
666 }
667
668 void VM::reset()
669 {
670         // reset all devices
671         for(DEVICE* device = first_device; device; device = device->next_device) {
672                 device->reset();
673         }
674 #if !defined(_FM77AV_VARIANTS) || defined(_FM8)
675 # if defined(USE_AY_3_8910_AS_PSG)
676         psg->set_reg(0x2e, 0);  // set prescaler
677         psg->write_signal(SIG_AY_3_891X_MUTE, 0x00, 0x01); // Okay?
678 # else  
679         psg->set_reg(0x27, 0); // stop timer
680         psg->set_reg(0x2e, 0);  // set prescaler
681         psg->write_signal(SIG_YM2203_MUTE, 0x00, 0x01); // Okay?
682 #endif
683 #endif
684 #if !defined(_FM8)
685         for(int i = 0; i < 3; i++) {
686                 opn[i]->set_reg(0x27, 0); // stop timer
687                 opn[i]->set_reg(0x2e, 0);       // set prescaler
688                 opn[i]->write_signal(SIG_YM2203_MUTE, 0x00, 0x01); // Okay?
689         }
690 #endif
691 }
692
693 void VM::special_reset()
694 {
695         // BREAK + RESET
696         mainio->reset();
697         mainmem->reset();
698         //mainio->write_signal(FM7_MAINIO_PUSH_BREAK, 1, 1);
699         //keyboard->write_signal(SIG_FM7KEY_OVERRIDE_PRESS_BREAK, 0xffffffff, 0xffffffff);
700         
701 #if defined(FM77AV_VARIANTS)    
702         mainio->write_signal(FM7_MAINIO_HOT_RESET, 1, 1);
703 #endif  
704         display->reset();
705         subcpu->reset();
706         maincpu->reset();
707         mainio->write_signal(FM7_MAINIO_PUSH_BREAK, 1, 1);
708         keyboard->write_signal(SIG_FM7KEY_OVERRIDE_PRESS_BREAK, 0xffffffff, 0xffffffff);
709         event->register_event(mainio, EVENT_UP_BREAK, 1000.0 * 1000.0, false, NULL);
710 }
711
712 void VM::run()
713 {
714         event->drive();
715 }
716
717 double VM::get_frame_rate()
718 {
719         return event->get_frame_rate();
720 }
721
722
723
724 // ----------------------------------------------------------------------------
725 // debugger
726 // ----------------------------------------------------------------------------
727
728 #ifdef USE_DEBUGGER
729 DEVICE *VM::get_cpu(int index)
730 {
731         if(index == 0) {
732                 return maincpu;
733         } else if(index == 1) {
734                 return subcpu;
735         }
736 #if defined(WITH_Z80)
737         else if(index == 2) {
738 # if defined(CAPABLE_JCOMMCARD)
739                 if(z80cpu == NULL) {
740                         return jsubcpu;
741                 }
742 # endif
743                 return z80cpu;
744         }
745 # if defined(CAPABLE_JCOMMCARD)
746         else if(index == 3) {
747                 return jsubcpu;
748         }
749 # endif
750 #else
751 # if defined(CAPABLE_JCOMMCARD)
752         else if(index == 2) {
753                 return jsubcpu;
754         }
755 # endif
756 #endif
757         return NULL;
758 }
759 #endif
760
761 // ----------------------------------------------------------------------------
762 // draw screen
763 // ----------------------------------------------------------------------------
764
765 void VM::draw_screen()
766 {
767         display->draw_screen();
768 }
769
770 void VM::initialize_sound(int rate, int samples)
771 {
772         // init sound manager
773         event->initialize_sound(rate, samples);
774         // init sound gen
775 #if defined(_FM8)
776         psg->initialize_sound(rate, (int)(4.9152 * 1000.0 * 1000.0 / 4.0), samples, 0, 0);
777 #else   
778         opn[0]->initialize_sound(rate, (int)(4.9152 * 1000.0 * 1000.0 / 4.0), samples, 0, 0);
779         opn[1]->initialize_sound(rate, (int)(4.9152 * 1000.0 * 1000.0 / 4.0), samples, 0, 0);
780         opn[2]->initialize_sound(rate, (int)(4.9152 * 1000.0 * 1000.0 / 4.0), samples, 0, 0);
781 # if !defined(_FM77AV_VARIANTS)   
782         psg->initialize_sound(rate, (int)(4.9152 * 1000.0 * 1000.0 / 4.0), samples, 0, 0);
783 # endif
784 # if defined(_FM77AV_VARIANTS)
785         keyboard_beep->initialize_sound(rate, 2400.0, 512);
786 # endif
787 #endif  
788         pcm1bit->initialize_sound(rate, 2000);
789         //drec->initialize_sound(rate, 0);
790 }
791
792 uint16_t* VM::create_sound(int* extra_frames)
793 {
794         uint16_t* p = event->create_sound(extra_frames);
795         return p;
796 }
797
798 int VM::get_sound_buffer_ptr()
799 {
800         int pos = event->get_sound_buffer_ptr();
801         return pos; 
802 }
803
804 #ifdef USE_SOUND_VOLUME
805 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
806 {
807 #if !defined(_FM77AV_VARIANTS)
808         if(ch-- == 0) {
809                 psg->set_volume(0, decibel_l, decibel_r);
810                 psg->set_volume(1, decibel_l, decibel_r);
811         } else
812 #endif
813 #if !defined(_FM8)              
814         if(ch-- == 0) {
815                 opn[0]->set_volume(0, decibel_l, decibel_r);
816         } else if(ch-- == 0) {
817                 opn[0]->set_volume(1, decibel_l, decibel_r);
818         } else if(ch-- == 0) {
819                 opn[1]->set_volume(0, decibel_l, decibel_r);
820         } else if(ch-- == 0) {
821                 opn[1]->set_volume(1, decibel_l, decibel_r);
822         } else if(ch-- == 0) {
823                 opn[2]->set_volume(0, decibel_l, decibel_r);
824         } else if(ch-- == 0) {
825                 opn[2]->set_volume(1, decibel_l, decibel_r);
826         } else
827 #endif  
828         if(ch-- == 0) {
829                 pcm1bit->set_volume(0, decibel_l, decibel_r);
830         } else if(ch-- == 0) {
831                 if(drec != NULL) drec->set_volume(0, decibel_l, decibel_r);
832         }
833 #if defined(_FM77AV_VARIANTS)
834         else if(ch-- == 0) {
835                 keyboard_beep->set_volume(0, decibel_l, decibel_r);
836         }
837 #endif
838         else if(ch-- == 0) {
839                 if(fdc != NULL) {
840                         fdc->get_context_noise_seek()->set_volume(0, decibel_l, decibel_r);
841                         fdc->get_context_noise_head_down()->set_volume(0, decibel_l, decibel_r);
842                         fdc->get_context_noise_head_up()->set_volume(0, decibel_l, decibel_r);
843                 }
844         } else if(ch-- == 0) {
845                 if(drec != NULL) {
846                         drec->get_context_noise_play()->set_volume(0, decibel_l, decibel_r);
847                         drec->get_context_noise_stop()->set_volume(0, decibel_l, decibel_r);
848                         drec->get_context_noise_fast()->set_volume(0, decibel_l, decibel_r);
849                 }
850         }
851 }
852 #endif
853
854 // ----------------------------------------------------------------------------
855 // notify key
856 // ----------------------------------------------------------------------------
857
858 void VM::key_down(int code, bool repeat)
859 {
860         if(!repeat) {
861                 keyboard->key_down(code);
862         }
863 }
864
865 void VM::key_up(int code)
866 {
867         keyboard->key_up(code);
868 }
869
870 bool VM::get_caps_locked()
871 {
872         return keyboard->get_caps_locked();
873 }
874
875 bool VM::get_kana_locked()
876 {
877         return keyboard->get_kana_locked();
878 }
879
880 // Get INS status.Important with FM-7 series (^_^;
881 uint32_t VM::get_extra_leds()
882 {
883         return keyboard->read_signal(SIG_FM7KEY_LED_STATUS);
884 }
885
886
887 // ----------------------------------------------------------------------------
888 // user interface
889 // ----------------------------------------------------------------------------
890
891 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
892 {
893         if(fdc != NULL) {
894                 fdc->open_disk(drv, file_path, bank);
895         }
896 }
897
898 void VM::close_floppy_disk(int drv)
899 {
900         if(fdc != NULL) {
901                 fdc->close_disk(drv);
902         }
903 }
904
905 bool VM::is_floppy_disk_inserted(int drv)
906 {
907         if(fdc != NULL) {
908                 return fdc->is_disk_inserted(drv);
909         } else {
910                 return false;
911         }
912 }
913
914 void VM::is_floppy_disk_protected(int drv, bool value)
915 {
916         if(fdc != NULL) {
917                 fdc->is_disk_protected(drv, value);
918         }
919 }
920
921 bool VM::is_floppy_disk_protected(int drv)
922 {
923         if(fdc != NULL) {
924                 return fdc->is_disk_protected(drv);
925         } else {
926                 return false;
927         }
928 }
929
930 uint32_t VM::is_floppy_disk_accessed()
931 {
932         // WILLFIX : Multiple FDC for 1M FD.
933 #if defined(_FM8) || (_FM7) || (_FMNEW7)
934         if(connect_320kfdc || connect_1Mfdc) {
935 #endif          
936                 return fdc->read_signal(0);
937 #if defined(_FM8) || (_FM7) || (_FMNEW7)
938         } else {
939                 return 0x00000000;
940         }
941 #endif  
942 }
943
944 void VM::play_tape(int drv, const _TCHAR* file_path)
945 {
946         if(drec != NULL) drec->play_tape(file_path);
947 }
948
949 void VM::rec_tape(int drv, const _TCHAR* file_path)
950 {
951         if(drec != NULL) drec->rec_tape(file_path);
952 }
953
954 void VM::close_tape(int drv)
955 {
956         emu->lock_vm();
957         if(drec != NULL) drec->close_tape();
958         emu->unlock_vm();
959 }
960
961 bool VM::is_tape_inserted(int drv)
962 {
963         if(drec != NULL) {
964                 return drec->is_tape_inserted();
965         }
966         return false;
967 }
968
969 bool VM::is_tape_playing(int drv)
970 {
971         if(drec != NULL) {
972                 return drec->is_tape_playing();
973         }
974         return false;
975 }
976
977 bool VM::is_tape_recording(int drv)
978 {
979         if(drec != NULL) {
980                 return drec->is_tape_recording();
981         }
982         return false;
983 }
984
985 int VM::get_tape_position(int drv)
986 {
987         if(drec != NULL) {
988                 return drec->get_tape_position();
989         }
990         return 0;
991 }
992
993 const _TCHAR* VM::get_tape_message(int drv)
994 {
995         if(drec != NULL) {
996                 return drec->get_message();
997         }
998         return NULL;
999 }
1000
1001 void VM::push_play(int drv)
1002 {
1003         if(drec != NULL) {
1004                 drec->set_ff_rew(0);
1005                 drec->set_remote(true);
1006         }
1007 }
1008
1009
1010 void VM::push_stop(int drv)
1011 {
1012         if(drec != NULL) {
1013                 drec->set_remote(false);
1014         }
1015 }
1016
1017 void VM::push_fast_forward(int drv)
1018 {
1019         if(drec != NULL) {
1020                 drec->set_ff_rew(1);
1021                 drec->set_remote(true);
1022         }
1023 }
1024
1025 void VM::push_fast_rewind(int drv)
1026 {
1027         if(drec != NULL) {
1028                 drec->set_ff_rew(-1);
1029                 drec->set_remote(true);
1030         }
1031 }
1032
1033 void VM::push_apss_forward(int drv)
1034 {
1035         if(drec != NULL) {
1036                 drec->do_apss(1);
1037         }
1038 }
1039
1040 void VM::push_apss_rewind(int drv)
1041 {
1042         if(drec != NULL) {
1043                 drec->do_apss(-1);
1044         }
1045 }
1046
1047 bool VM::is_frame_skippable()
1048 {
1049         return event->is_frame_skippable();
1050 }
1051
1052 void VM::update_dipswitch()
1053 {
1054 #if defined(WITH_Z80)
1055         g_intr_irq->write_signal(SIG_AND_BIT_0, ((config.dipswitch & FM7_DIPSW_Z80_IRQ_ON) != 0) ? 1 : 0, 1);
1056         g_intr_firq->write_signal(SIG_AND_BIT_0, ((config.dipswitch & FM7_DIPSW_Z80_FIRQ_ON) != 0) ? 1 : 0, 1);
1057         g_nmi->write_signal(SIG_AND_BIT_0, ((config.dipswitch & FM7_DIPSW_Z80_NMI_ON) != 0) ? 1 : 0, 1);
1058 #endif
1059 }
1060
1061 void VM::set_cpu_clock(DEVICE *cpu, uint32_t clocks) {
1062         event->set_secondary_cpu_clock(cpu, clocks);
1063 }
1064
1065 #if defined(USE_BUBBLE1)
1066 void VM::open_bubble_casette(int drv, const _TCHAR *path, int bank)
1067 {
1068         if((drv >= 2) || (drv < 0)) return;
1069         if(bubble_casette[drv] == NULL) return;
1070         bubble_casette[drv]->open((_TCHAR *)path, bank);
1071 }
1072
1073 void VM::close_bubble_casette(int drv)
1074 {
1075         if((drv >= 2) || (drv < 0)) return;
1076         if(bubble_casette[drv] == NULL) return;
1077         bubble_casette[drv]->close();
1078 }
1079
1080 bool VM::is_bubble_casette_inserted(int drv)
1081 {
1082         if((drv >= 2) || (drv < 0)) return false;
1083         if(bubble_casette[drv] == NULL) return false;
1084         return bubble_casette[drv]->is_bubble_inserted();
1085 }
1086
1087 bool VM::is_bubble_casette_protected(int drv)
1088 {
1089         if((drv >= 2) || (drv < 0)) return false;
1090         if(bubble_casette[drv] == NULL) return false;
1091         return bubble_casette[drv]->is_bubble_protected();
1092 }
1093
1094 void VM::is_bubble_casette_protected(int drv, bool flag)
1095 {
1096         if((drv >= 2) || (drv < 0)) return;
1097         if(bubble_casette[drv] == NULL) return;
1098         bubble_casette[drv]->set_bubble_protect(flag);
1099 }
1100 #endif
1101
1102
1103 #define STATE_VERSION   8
1104 void VM::save_state(FILEIO* state_fio)
1105 {
1106         state_fio->FputUint32_BE(STATE_VERSION);
1107         state_fio->FputBool(connect_320kfdc);
1108         state_fio->FputBool(connect_1Mfdc);
1109         for(DEVICE* device = first_device; device; device = device->next_device) {
1110                 const char *name = typeid(*device).name() + 6; // skip "class "
1111                 
1112                 state_fio->FputInt32(strlen(name));
1113                 state_fio->Fwrite(name, strlen(name), 1);
1114                 device->save_state(state_fio);
1115         }
1116 }
1117
1118 bool VM::load_state(FILEIO* state_fio)
1119 {
1120         uint32_t version = state_fio->FgetUint32_BE();
1121         if(version != STATE_VERSION) {
1122                 return false;
1123         }
1124         connect_320kfdc = state_fio->FgetBool();
1125         connect_1Mfdc = state_fio->FgetBool();
1126         for(DEVICE* device = first_device; device; device = device->next_device) {
1127                 const char *name = typeid(*device).name() + 6; // skip "class "
1128                 
1129                 if(!(state_fio->FgetInt32() == strlen(name) && state_fio->Fcompare(name, strlen(name)))) {
1130                         printf("Load Error: DEVID=%d\n", device->this_device_id);
1131                         return false;
1132                 }
1133                 if(!device->load_state(state_fio)) {
1134                         printf("Load Error: DEVID=%d\n", device->this_device_id);
1135                         return false;
1136                 }
1137         }
1138         return true;
1139 }
1140
1141 #ifdef USE_DIG_RESOLUTION
1142 void VM::get_screen_resolution(int *w, int *h)
1143 {
1144         switch(display->get_screen_mode()) {
1145         case DISPLAY_MODE_8_200L:
1146         case DISPLAY_MODE_8_200L_TEXT:
1147                 *w = 640;
1148                 *h = 200;
1149                 break;
1150         case DISPLAY_MODE_8_400L:
1151         case DISPLAY_MODE_8_400L_TEXT:
1152                 *w = 640;
1153                 *h = 400;
1154                 break;
1155         case DISPLAY_MODE_4096:
1156         case DISPLAY_MODE_256k:
1157                 *w = 320;
1158                 *h = 200;
1159                 break;
1160         default:
1161                 *w = 640;
1162                 *h = 200;
1163                 break;
1164         }
1165 }
1166 #endif
1167
1168 bool VM::is_screen_changed()
1169 {
1170         bool f = true;
1171 #if defined(USE_MINIMUM_RENDERING)
1172         f = display->screen_update();
1173         display->reset_screen_update();
1174 #endif  
1175         return f;
1176 }