OSDN Git Service

[VM][WIP] Merging upstream 2022-09-09.Still be imcompleted.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Sat, 4 Mar 2023 19:41:30 +0000 (04:41 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Sat, 4 Mar 2023 19:41:30 +0000 (04:41 +0900)
- This still working in progress.May or not may available to build.
- Upstream changes are only implemented to DEVICE classes.Still not implement  to VMs.

[VM][DEVICE] Sync SIGNAL enumelation values to upstreeam, move some unique values to 190 to 199 .
[VM][Z80][WIP] Add variable clock feature for primary CPU via SIG_CPU_WAIT_FACTOR .
[VM][I386_NP21][FMTOWNS] Fix around variable CPU clock.This still not implement to PC-9801 and N5200 (and others).
[General] Update SOVERSIONs.

21 files changed:
source/src/config.cpp
source/src/config.h
source/src/debugger.cpp
source/src/qt/CMakeLists.txt
source/src/qt/avio/CMakeLists.txt
source/src/qt/emuutils/CMakeLists.txt
source/src/qt/gui/CMakeLists.txt
source/src/vm/common_vm/CMakeLists.txt
source/src/vm/device.cpp
source/src/vm/device.h
source/src/vm/device_params.h
source/src/vm/event.cpp
source/src/vm/event.h
source/src/vm/fmgen/CMakeLists.txt
source/src/vm/fmtowns/towns_memory.cpp
source/src/vm/i386.h
source/src/vm/i386_np21.cpp
source/src/vm/i386_np21.h
source/src/vm/mc6809.h
source/src/vm/z80.cpp
source/src/vm/z80.h

index 3db4474..4046baa 100644 (file)
@@ -33,12 +33,12 @@ BOOL MyWritePrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, int Value, L
 {
        return MyWritePrivateProfileString(lpAppName, lpKeyName, create_string(_T("%d"), Value), lpFileName);
 }
+
 BOOL MyWritePrivateProfileBool(LPCTSTR lpAppName, LPCTSTR lpKeyName, bool Value, LPCTSTR lpFileName)
 {
        return MyWritePrivateProfileString(lpAppName, lpKeyName, create_string(_T("%d"), Value ? 1 : 0), lpFileName);
 }
+
 bool MyGetPrivateProfileBool(LPCTSTR lpAppName, LPCTSTR lpKeyName, bool bDefault, LPCTSTR lpFileName)
 {
        return (MyGetPrivateProfileInt(lpAppName, lpKeyName, bDefault ? 1 : 0, lpFileName) != 0);
@@ -48,9 +48,9 @@ void initialize_config()
 {
        // initial settings
        memset(&config, 0, sizeof(config_t));
-       config.window_mode = 1; 
+       config.window_mode = 1;
        // memo: set only non zero value
-       config.full_speed = false;      
+       config.full_speed = false;
 
        // console / telnet
        config.use_telnet = false;
@@ -121,9 +121,9 @@ void initialize_config()
                        config.swap_audio_byteorder[drv] = false;
                }
        #endif
-               
-       config.compress_state = true;
-       
+
+       config.compress_state = config.drive_vm_in_opecode = true;
+
        // screen
        #ifndef ONE_BOARD_MICRO_COMPUTER
                config.fullscreen_stretch_type = 1;     // Stretch (Aspect)
@@ -172,7 +172,7 @@ void initialize_config()
        // debug
        config.special_debug_fdc = false;
        config.print_statistics = false;
-       
+
        // win32
        #if defined(_WIN32) && !defined(_USE_QT)
                #ifndef ONE_BOARD_MICRO_COMPUTER
@@ -182,39 +182,39 @@ void initialize_config()
                config.use_dinput = true;
                config.show_status_bar = true;
        #endif
-       
+
        // qt
        #ifdef _USE_QT
                config.use_separate_thread_draw = true;
-               config.use_osd_virtual_media = true;            
+               config.use_osd_virtual_media = true;
                config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_ES;
                config.render_major_version = 2; // For crash with some devices.
                config.render_minor_version = 0;
                config.rendering_type = CONFIG_RENDER_TYPE_STD;
-               
+
                config.use_opengl_scanline = false;
                config.opengl_scanline_vert = false;
                config.opengl_scanline_horiz = false;
                config.use_opengl_filters = false;
                config.opengl_filter_num = 0;
                config.focus_with_click = false;
-               
+
                config.video_width = 640;
                config.video_height = 480;
                config.video_codec_type = 0; // MPEG4
-       
+
                config.video_h264_bitrate = 512;
                config.video_h264_bframes = 4;
                config.video_h264_b_adapt = 2;
                config.video_h264_minq = 14;
                config.video_h264_maxq = 25;
                config.video_h264_subme = 8;
-               
+
                config.video_mpeg4_bitrate = 512;
                config.video_mpeg4_bframes = 4;
                config.video_mpeg4_minq = 1;
                config.video_mpeg4_maxq = 20;
-               
+
                config.audio_codec_type = 0;
                config.video_threads = 0;
                config.audio_bitrate = 160;
@@ -230,8 +230,8 @@ void initialize_config()
                }
                config.state_log_to_console = false;
                config.state_log_to_syslog = false;
-               config.state_log_to_recording = false; 
-               
+               config.state_log_to_recording = false;
+
                config.rendering_type = CONFIG_RENDER_TYPE_STD;
                config.virtual_media_position = 2; // Down.
                for(int drv = 0; drv < 16; drv++) {
@@ -241,9 +241,9 @@ void initialize_config()
                config.cursor_as_ten_key = CONFIG_CURSOR_AS_CURSOR;
                memset(config.debugwindow_font, 0x00, sizeof(config.debugwindow_font));
                memset(config.logwindow_font, 0x00, sizeof(config.logwindow_font));
-               
+
        #if defined(_FM7) || defined(_FMNEW7) || defined(_FM8) \
-           || defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)             
+           || defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
                config.numpad_enter_as_fullkey = false;
        #else
                config.numpad_enter_as_fullkey = true;
@@ -262,7 +262,7 @@ void load_config(const _TCHAR *config_path)
        int drv, i;
        // initial settings
        initialize_config();
-       
+
        // control
        #ifdef USE_BOOT_MODE
                config.boot_mode = MyGetPrivateProfileInt(_T("Control"), _T("BootMode"), config.boot_mode, config_path);
@@ -280,7 +280,7 @@ void load_config(const _TCHAR *config_path)
                                MyGetPrivateProfileInt(_T("Control"),
                                                                           create_string(_T("MachineFeatures%d"), ii),
                                                                           config.machine_features[ii], config_path);
-                       
+
                }
        #endif
        #ifdef USE_DEVICE_TYPE
@@ -333,7 +333,8 @@ void load_config(const _TCHAR *config_path)
                        config.baud_high[drv] = MyGetPrivateProfileBool(_T("Control"), create_string(_T("BaudHigh%d"), drv + 1), config.baud_high[drv], config_path);
                }
        #endif
-       config.compress_state = MyGetPrivateProfileBool(_T("Control"), _T("CompressState"), config.compress_state, config_path);                
+       config.compress_state = MyGetPrivateProfileBool(_T("Control"), _T("CompressState"), config.compress_state, config_path);
+       config.drive_vm_in_opecode = MyGetPrivateProfileBool(_T("Control"), _T("DriveVMInOpecode"), config.drive_vm_in_opecode, config_path);
                // recent files
        #ifdef USE_CART
                MyGetPrivateProfileString(_T("RecentFiles"), _T("InitialCartDir"), _T(""), config.initial_cart_dir, _MAX_PATH, config_path);
@@ -408,7 +409,7 @@ void load_config(const _TCHAR *config_path)
                        }
                }
        #endif
-       
+
        // screen
        #ifndef ONE_BOARD_MICRO_COMPUTER
                config.window_mode = MyGetPrivateProfileInt(_T("Screen"), _T("WindowMode"), config.window_mode, config_path);
@@ -419,7 +420,7 @@ void load_config(const _TCHAR *config_path)
 //             #endif
        #endif
 
-       
+
        // filter
        #ifdef USE_SCREEN_FILTER
                config.filter_type = MyGetPrivateProfileInt(_T("Screen"), _T("FilterType"), config.filter_type, config_path);
@@ -457,7 +458,7 @@ void load_config(const _TCHAR *config_path)
                        #endif
                }
        #endif
-       
+
        #if defined(_WIN32) && !defined(_USE_QT)
                // for compatibilities
                #ifdef _X1_H_
@@ -521,7 +522,7 @@ void load_config(const _TCHAR *config_path)
        // qt
        #ifdef _USE_QT
                config.use_separate_thread_draw = MyGetPrivateProfileBool(_T("Qt"), _T("UseSeparateThreadDraw"), config.use_separate_thread_draw, config_path);
-               config.use_osd_virtual_media = MyGetPrivateProfileBool(_T("Qt"), _T("UseOSDVirtualMedia"), config.use_osd_virtual_media, config_path); 
+               config.use_osd_virtual_media = MyGetPrivateProfileBool(_T("Qt"), _T("UseOSDVirtualMedia"), config.use_osd_virtual_media, config_path);
                config.use_opengl_scanline = MyGetPrivateProfileBool(_T("Qt"), _T("UseOpenGLScanLine"), config.use_opengl_scanline, config_path);
                config.opengl_scanline_vert = MyGetPrivateProfileBool(_T("Qt"), _T("OpenGLScanLineVert"), config.opengl_scanline_vert, config_path);;
                config.opengl_scanline_horiz = MyGetPrivateProfileBool(_T("Qt"), _T("OpenGLScanLineHoriz"), config.opengl_scanline_horiz, config_path);;
@@ -534,7 +535,7 @@ void load_config(const _TCHAR *config_path)
 
                config.general_sound_level = MyGetPrivateProfileInt(_T("Qt"), _T("GeneralSoundLevel"), config.general_sound_level, config_path);
                config.focus_with_click = MyGetPrivateProfileBool(_T("Qt"), _T("FocusWithClick"), config.focus_with_click, config_path);
-               
+
                if(config.rendering_type < 0) config.rendering_type = 0;
                if(config.rendering_type >= CONFIG_RENDER_TYPE_END) config.rendering_type = CONFIG_RENDER_TYPE_END - 1;
 
@@ -564,49 +565,49 @@ void load_config(const _TCHAR *config_path)
                if(config.video_width < 128) config.video_width = 128;
                config.video_height  = MyGetPrivateProfileInt(_T("Qt"), _T("VideoHeight"), 480, config_path);
                if(config.video_height < 80) config.video_height = 80;
-               
+
                config.video_codec_type = MyGetPrivateProfileInt(_T("Qt"), _T("VideoCodecType"), 1, config_path);
                if(config.video_codec_type > 1) config.video_codec_type = 1;
                if(config.video_codec_type < 0) config.video_codec_type = 0;
-               
+
                config.audio_codec_type = MyGetPrivateProfileInt(_T("Qt"), _T("AudioCodecType"), 0, config_path);
                if(config.video_codec_type > 2) config.audio_codec_type = 2;
                if(config.video_codec_type < 0) config.audio_codec_type = 0;
-               
+
                config.video_h264_bitrate = MyGetPrivateProfileInt(_T("Qt"), _T("H264Bitrate"), 3500, config_path);
                if(config.video_h264_bitrate < 64) config.video_h264_bitrate = 64;
-               
+
                config.video_h264_bframes = MyGetPrivateProfileInt(_T("Qt"), _T("H264BFrames"), 4, config_path);
                if(config.video_h264_bframes < 0) config.video_h264_bframes = 0;
                if(config.video_h264_bframes > 10) config.video_h264_bframes = 10;
-               
+
                config.video_h264_b_adapt = MyGetPrivateProfileInt(_T("Qt"), _T("H264BAdapt"), 2, config_path);
                if(config.video_h264_b_adapt < 0) config.video_h264_b_adapt = 0;
                if(config.video_h264_b_adapt > 2) config.video_h264_b_adapt = 2;
-               
+
                config.video_h264_subme   = MyGetPrivateProfileInt(_T("Qt"), _T("H264Subme"), 7, config_path);
                if(config.video_h264_subme < 0) config.video_h264_subme = 0;
                if(config.video_h264_subme > 11) config.video_h264_subme = 11;
-               
+
                config.video_h264_minq   = MyGetPrivateProfileInt(_T("Qt"), _T("H264MinQ"), 15, config_path);
                if(config.video_h264_minq < 0) config.video_h264_minq = 0;
                if(config.video_h264_minq > 63) config.video_h264_minq = 63;
-               
+
                config.video_h264_maxq   = MyGetPrivateProfileInt(_T("Qt"), _T("H264MaxQ"), 28, config_path);
                if(config.video_h264_maxq < 0) config.video_h264_maxq = 0;
                if(config.video_h264_maxq > 63) config.video_h264_maxq = 63;
-               
+
                config.video_mpeg4_bitrate = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4Bitrate"), 1500, config_path);
                if(config.video_mpeg4_bitrate < 64) config.video_mpeg4_bitrate = 64;
-               
+
                config.video_mpeg4_bframes = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4BFrames"), 2, config_path);
                if(config.video_mpeg4_bframes < 0) config.video_mpeg4_bframes = 0;
                if(config.video_mpeg4_bframes > 10) config.video_mpeg4_bframes = 10;
-               
+
                config.video_mpeg4_minq   = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4MinQ"), 1, config_path);
                if(config.video_mpeg4_minq < 1) config.video_mpeg4_minq = 1;
                if(config.video_mpeg4_minq > 31) config.video_mpeg4_minq = 31;
-               
+
                config.video_mpeg4_maxq   = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4MaxQ"), 15, config_path);
                if(config.video_mpeg4_maxq < 1) config.video_mpeg4_maxq = 1;
                if(config.video_mpeg4_maxq > 31) config.video_mpeg4_maxq = 31;
@@ -616,22 +617,22 @@ void load_config(const _TCHAR *config_path)
                        config.video_mpeg4_maxq  = config.video_mpeg4_minq;
                        config.video_mpeg4_minq = n;
                }
-               
+
                config.video_threads = MyGetPrivateProfileInt(_T("Qt"), _T("VideoThreads"), 0, config_path);
                if(config.video_threads < 0) config.video_threads = 0;
                if(config.video_threads > 16) config.video_threads = 16;
-               
+
                config.audio_bitrate = MyGetPrivateProfileInt(_T("Qt"), _T("AudioBitrate"), 224, config_path);
                if(config.audio_bitrate < 16) config.audio_bitrate = 16;
                if(config.audio_bitrate > 448) config.audio_bitrate = 448;
-               
+
                config.video_frame_rate = MyGetPrivateProfileInt(_T("Qt"), _T("VideoFramerate"), 60, config_path);
                if(config.video_frame_rate < 15) config.video_frame_rate = 15;
                if(config.video_frame_rate > 75) config.video_frame_rate = 75;
                // Logging
                config.log_to_syslog = MyGetPrivateProfileBool(_T("Qt"), _T("WriteToSyslog"), config.log_to_syslog, config_path);
                config.log_to_console = MyGetPrivateProfileBool(_T("Qt"), _T("WriteToConsole"), config.log_to_console, config_path);
-               
+
                for(int ii = 0; ii < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1) ; ii++) {
                        uint32_t flags = 0;
                        flags = MyGetPrivateProfileInt(_T("Qt"), create_string(_T("SyslogEnabled%d"), ii), 0xffff, config_path);
@@ -658,7 +659,7 @@ void load_config(const _TCHAR *config_path)
                config.virtual_media_position = MyGetPrivateProfileInt(_T("Qt"), _T("UiVirtualMediaPosition"), config.virtual_media_position, config_path);
        #endif
 }
-               
+
 void save_config(const _TCHAR *config_path)
 {
        int drv, i;
@@ -672,8 +673,8 @@ void save_config(const _TCHAR *config_path)
                pt->Fclose();
                delete pt;
        }
-       
-#endif 
+
+#endif
        // control
        #ifdef USE_BOOT_MODE
                MyWritePrivateProfileInt(_T("Control"), _T("BootMode"), config.boot_mode, config_path);
@@ -690,7 +691,7 @@ void save_config(const _TCHAR *config_path)
                        MyWritePrivateProfileInt(_T("Control"),
                                                                           create_string(_T("MachineFeatures%d"), ii),
                                                                           config.machine_features[ii], config_path);
-                       
+
                }
        #endif
        #ifdef USE_DEVICE_TYPE
@@ -744,9 +745,8 @@ void save_config(const _TCHAR *config_path)
                }
        #endif
        MyWritePrivateProfileBool(_T("Control"), _T("CompressState"), config.compress_state, config_path);
-       
-       // recent files
-       
+       MyWritePrivateProfileBool(_T("Control"), _T("DriveVMInOpecode"), config.drive_vm_in_opecode, config_path);
+
        // recent files
        #ifdef USE_CART
                MyWritePrivateProfileString(_T("RecentFiles"), _T("InitialCartDir"), config.initial_cart_dir, config_path);
@@ -797,7 +797,7 @@ void save_config(const _TCHAR *config_path)
                        }
 
                }
-               
+
        #endif
        #ifdef USE_LASER_DISC
                MyWritePrivateProfileString(_T("RecentFiles"), _T("InitialLaserDiscDir"), config.initial_laser_disc_dir, config_path);
@@ -823,7 +823,7 @@ void save_config(const _TCHAR *config_path)
                        }
                }
        #endif
-       
+
        // screen
        #ifndef ONE_BOARD_MICRO_COMPUTER
                MyWritePrivateProfileInt(_T("Screen"), _T("WindowMode"), config.window_mode, config_path);
@@ -838,7 +838,7 @@ void save_config(const _TCHAR *config_path)
        #ifdef USE_SCREEN_FILTER
                MyWritePrivateProfileInt(_T("Screen"), _T("FilterType"), config.filter_type, config_path);
        #endif
-               
+
        // sound
                MyWritePrivateProfileInt(_T("Sound"), _T("Frequency"), config.sound_frequency, config_path);
                MyWritePrivateProfileInt(_T("Sound"), _T("Latency"), config.sound_latency, config_path);
@@ -867,7 +867,7 @@ void save_config(const _TCHAR *config_path)
                MyWritePrivateProfileString(_T("Sound"), _T("YM2151GenDll"), config.mame2151_dll_path, config_path);
                MyWritePrivateProfileString(_T("Sound"), _T("YM2608GenDll"), config.mame2608_dll_path, config_path);
        #endif
-       
+
        // input
        #ifdef USE_JOYSTICK
                for(int i = 0; i < 4; i++) {
@@ -881,7 +881,7 @@ void save_config(const _TCHAR *config_path)
                for(int j = 0; j < 4; j++) {
                        MyWritePrivateProfileBool(_T("Input"), create_string(_T("JoyEmulateDpad%d"), j), config.emulated_joystick_dpad[j], config_path);
                }
-               
+
                MyWritePrivateProfileBool(_T("Input"), _T("UseJoyToKey"), config.use_joy_to_key, config_path);
                MyWritePrivateProfileInt(_T("Input"), _T("JoyToKeyType"), config.joy_to_key_type, config_path);
                MyWritePrivateProfileBool(_T("Input"), _T("JoyToKeyNumPad5"), config.joy_to_key_numpad5, config_path);
@@ -901,7 +901,7 @@ void save_config(const _TCHAR *config_path)
                MyWritePrivateProfileString(_T("Printer"), _T("PrinterDll"), config.printer_dll_path, config_path);
        #endif
 
-       
+
        // win32
        #if defined(_WIN32) && !defined(_USE_QT)
                MyWritePrivateProfileBool(_T("Win32"), _T("UseTelnet"), config.use_telnet, config_path);
@@ -916,7 +916,7 @@ void save_config(const _TCHAR *config_path)
        #endif
        #ifdef _USE_QT
                MyWritePrivateProfileBool(_T("Qt"), _T("UseSeparateThreadDraw"), config.use_separate_thread_draw, config_path);
-               MyWritePrivateProfileBool(_T("Qt"), _T("UseOSDVirtualMedia"), config.use_osd_virtual_media, config_path); 
+               MyWritePrivateProfileBool(_T("Qt"), _T("UseOSDVirtualMedia"), config.use_osd_virtual_media, config_path);
                MyWritePrivateProfileBool(_T("Qt"), _T("UseOpenGLScanLine"), config.use_opengl_scanline, config_path);
                MyWritePrivateProfileBool(_T("Qt"), _T("OpenGLScanLineVert"), config.opengl_scanline_vert, config_path);;
                MyWritePrivateProfileBool(_T("Qt"), _T("OpenGLScanLineHoriz"), config.opengl_scanline_horiz, config_path);;
@@ -946,34 +946,34 @@ void save_config(const _TCHAR *config_path)
                for(i = 0; i < 16; i++) {
                        _TCHAR name[256];
                        my_stprintf_s(name, 255, _T("AssignedJoystick%d"), i + 1);
-                       MyWritePrivateProfileString(_T("Qt"), (const _TCHAR *)name, 
+                       MyWritePrivateProfileString(_T("Qt"), (const _TCHAR *)name,
                                                                                config.assigned_joystick_name[i], config_path);
                }
-       #endif  
+       #endif
                MyWritePrivateProfileInt(_T("Qt"), _T("VideoWidth"), config.video_width, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("VideoHeight"), config.video_height, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("VideoCodecType"), config.video_codec_type, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("AudioCodecType"), config.audio_codec_type, config_path);
-               
+
                MyWritePrivateProfileInt(_T("Qt"), _T("H264Bitrate"), config.video_h264_bitrate, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("H264BFrames"), config.video_h264_bframes, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("H264BAdapt"), config.video_h264_b_adapt, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("H264MinQ"), config.video_h264_minq, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("H264MaxQ"), config.video_h264_maxq, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("H264Subme"), config.video_h264_subme, config_path);
-               
+
                MyWritePrivateProfileInt(_T("Qt"), _T("MPEG4Bitrate"), config.video_mpeg4_bitrate, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("MPEG4BFrames"), config.video_mpeg4_bframes, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("MPEG4MinQ"), config.video_mpeg4_minq, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("MPEG4MaxQ"), config.video_mpeg4_maxq, config_path);
-               
+
                MyWritePrivateProfileInt(_T("Qt"), _T("VideoThreads"), config.video_threads, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("AudioBitrate"), config.audio_bitrate, config_path);
                MyWritePrivateProfileInt(_T("Qt"), _T("VideoFramerate"), config.video_frame_rate, config_path);
-               
+
                MyWritePrivateProfileBool(_T("Qt"), _T("WriteToSyslog"), config.log_to_syslog, config_path);
                MyWritePrivateProfileBool(_T("Qt"), _T("WriteToConsole"), config.log_to_console, config_path);
-               
+
                for(int ii = 0; ii < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1) ; ii++) {
                        uint32_t flags = 0;
                        flags = 0;
@@ -982,14 +982,14 @@ void save_config(const _TCHAR *config_path)
                                if(config.dev_log_to_syslog[ii][jj]) flags |= 0x0001;
                        }
                        MyWritePrivateProfileInt(_T("Qt"), create_string(_T("SyslogEnabled%d"), ii), flags, config_path);
-                       
+
                        flags = 0;
                        for(int jj = 0; jj < 8; jj++) {
                                flags <<= 1;
                                if(config.dev_log_to_console[ii][jj]) flags |= 0x0001;
                        }
                        MyWritePrivateProfileInt(_T("Qt"), create_string(_T("ConsoleLogEnabled%d"), ii), flags, config_path);
-                       
+
                        flags = 0;
                        for(int jj = 0; jj < 8; jj++) {
                                flags <<= 1;
@@ -1000,9 +1000,9 @@ void save_config(const _TCHAR *config_path)
                MyWritePrivateProfileBool(_T("Qt"), _T("StateLogToConsole"), config.state_log_to_console, config_path);
                MyWritePrivateProfileBool(_T("Qt"), _T("StateLogToSyslog"), config.state_log_to_syslog, config_path);
                MyWritePrivateProfileBool(_T("Qt"), _T("StateLogToRecording"), config.state_log_to_recording, config_path);
-               
+
                MyWritePrivateProfileInt(_T("Qt"), _T("UiVirtualMediaPosition"), config.virtual_media_position, config_path);
-       #endif  
+       #endif
 }
 
 #define STATE_VERSION  7
@@ -1010,7 +1010,7 @@ void save_config(const _TCHAR *config_path)
 bool process_config_state(void *f, bool loading)
 {
        FILEIO *state_fio = (FILEIO *)f;
-       
+
        if(!state_fio->StateCheckUint32(STATE_VERSION)) {
                return false;
        }
@@ -1058,7 +1058,7 @@ bool process_config_state(void *f, bool loading)
        #endif
        state_fio->StateValue(config.sound_frequency);
        state_fio->StateValue(config.sound_latency);
-       
+
        #if defined(USE_FIXED_CONFIG) || defined(USE_SCANLINE)
        state_fio->StateValue(config.scan_line);
        #endif
@@ -1073,7 +1073,6 @@ bool process_config_state(void *f, bool loading)
        state_fio->StateValue(config.current_ram_size);
        #endif
        state_fio->StateValue(config.cpu_power);
-       
+
        return true;
 }
-
index d77f7ba..561dcf0 100644 (file)
@@ -49,7 +49,7 @@ enum {
        CONFIG_HOST_KEYBOARD_TYPE_AT_MISC = 0x00ff0000,
        CONFIG_HOST_KEYBOARD_TYPE_PC98    = 0x00980000,
        CONFIG_HOST_KEYBOARD_TYPE_MAC     = 0x00fe0000,
-};     
+};
 
 enum {
        CONFIG_HOST_KEYBOARD_AT_106JP    = CONFIG_HOST_KEYBOARD_TYPE_AT_JP + 106,
@@ -63,7 +63,7 @@ enum {
        CONFIG_HOST_KEYBOARD_MAC_US      = CONFIG_HOST_KEYBOARD_TYPE_MAC + 0,
        CONFIG_HOST_KEYBOARD_MAC_JP      = CONFIG_HOST_KEYBOARD_TYPE_MAC + 1,
        CONFIG_HOST_KEYBOARD_MAC_ANOTHER = CONFIG_HOST_KEYBOARD_TYPE_MAC + 0xff,
-};     
+};
 
 enum {
        CONFIG_CURSOR_AS_CURSOR = 0,
@@ -109,7 +109,7 @@ bool process_config_state(void *f, bool loading);
  * Qt:
  *  To reduce time to build, compiling common blocks of GUI at once.
  *  So, you should not separate items with #ifdef.
- */ 
+ */
 typedef struct {
        // control
        #if defined(USE_FIXED_CONFIG) || defined(USE_BOOT_MODE)
@@ -131,10 +131,10 @@ typedef struct {
                int keyboard_type;
        #endif
        #if defined(USE_FIXED_CONFIG) || defined(USE_MOUSE_TYPE)
-               int mouse_type; /*!< Emulated type of mouse by VM */ 
+               int mouse_type; /*!< Emulated type of mouse by VM */
        #endif
        #if defined(USE_FIXED_CONFIG) || defined(USE_JOYSTICK_TYPE)
-               int joystick_type; /*!< Emulated type of joystick by VM */ 
+               int joystick_type; /*!< Emulated type of joystick by VM */
        #endif
        #if defined(USE_FIXED_CONFIG) || defined(USE_SOUND_TYPE)
                int sound_type;
@@ -164,10 +164,10 @@ typedef struct {
        #if defined(USE_SHARED_DLL) || defined(USE_VARIABLE_MEMORY)
        uint32_t current_ram_size;
        #endif
-       bool compress_state;
+       bool full_speed, drive_vm_in_opecode;
        int cpu_power;
        bool full_speed;
-       
+
        // recent files
        #if defined(USE_SHARED_DLL) || defined(USE_CART)
                _TCHAR initial_cart_dir[_MAX_PATH];
@@ -215,7 +215,7 @@ typedef struct {
        //      #if defined(USE_FIXED_CONFIG) || defined(USE_SCREEN_ROTATE)
                int rotate_type;
        //      #endif
-       
+
        // filter
        #if defined(USE_FIXED_CONFIG) || defined(USE_SCREEN_FILTER)
                int filter_type;
@@ -232,15 +232,15 @@ typedef struct {
        bool use_opengl_filters;
        bool focus_with_click;
        int opengl_filter_num;
-       
+
        // STAGED CONFIG VALUES
        bool swap_kanji_pause;
        int  cursor_as_ten_key;
        bool numpad_enter_as_fullkey;
        int host_keyboard_type;
-       
+
        /*
-        * TYPE : 
+        * TYPE :
         *    0 : OpenGL/Main Profile
         *    1 : OpenGL/Core Profile
         *    2 : OpenGL ES
@@ -249,7 +249,7 @@ typedef struct {
         *   24 : DirectDraw (Will not implement)
         *   25 : SDLFB(Will not implement)
      *   32 : DirectX(Will not implement)
-        */ 
+        */
        int render_platform;
        int render_major_version;
        int render_minor_version;
@@ -260,16 +260,16 @@ typedef struct {
        int debugwindow_height;
        int logwindow_width;
        int logwindow_height;
-       
-#endif 
-       
+
+#endif
+
        // sound
        int sound_frequency;
        int sound_latency;
        bool sound_strict_rendering;
        _TCHAR sound_device_name[1024];
-       
-#if defined(_USE_QT)   
+
+#if defined(_USE_QT)
        int general_sound_level;
 #endif
 #if defined(USE_FIXED_CONFIG) || defined(USE_FLOPPY_DISK)
@@ -307,8 +307,8 @@ typedef struct {
 #if defined(USE_FIXED_CONFIG) || defined(USE_PRINTER)
        _TCHAR printer_dll_path[_MAX_PATH];
 #endif
-       // debug 
-       bool special_debug_fdc; 
+       // debug
+       bool special_debug_fdc;
        bool print_statistics;
 
        bool use_telnet;
@@ -329,7 +329,7 @@ typedef struct {
        int video_height;
        int video_codec_type;
        int audio_codec_type;
-       
+
        int video_h264_bitrate;
        int video_h264_bframes;
        int video_h264_b_adapt;
@@ -341,7 +341,7 @@ typedef struct {
        int video_mpeg4_bframes;
        int video_mpeg4_minq;
        int video_mpeg4_maxq;
-       
+
        int video_threads;
        int audio_bitrate;
        int video_frame_rate; // FPS * 1000.0
@@ -354,7 +354,7 @@ typedef struct {
        bool state_log_to_console;
        bool state_log_to_syslog;
        bool state_log_to_recording;
-       
+
        int rendering_type;
 
        int virtual_media_position; // -1 = none, 1, 2, 3, 4 = LRUD
@@ -373,4 +373,3 @@ extern config_t DLL_PREFIX_I config;
 #endif
 
 #endif
-
index fbc8e93..0f7c9aa 100644 (file)
@@ -41,11 +41,11 @@ void my_printf(OSD_BASE *osd, const _TCHAR *format, ...)
 {
        _TCHAR buffer[8192];
        va_list ap;
-       
+
        va_start(ap, format);
        my_vstprintf_s(buffer, array_length(buffer), format, ap);
        va_end(ap);
-       
+
        if(logfile != NULL && logfile->IsOpened()) {
                logfile->Fwrite(buffer, _tcslen(buffer) * sizeof(_TCHAR), 1);
        }
@@ -64,12 +64,12 @@ uint32_t my_hexatoi(DEVICE *device, const _TCHAR *str)
 {
        _TCHAR tmp[1024], *s;
        symbol_t *first_symbol = NULL;
-       
+
        if(str == NULL || _tcslen(str) == 0) {
                return 0;
        }
        my_tcscpy_s(tmp, array_length(tmp), str);
-       
+
        if(device != NULL) {
                DEBUGGER *debugger = (DEBUGGER *)device->get_debugger();
                if(debugger != NULL) {
@@ -122,7 +122,7 @@ uint16_t my_hexatow(char *value)
 const _TCHAR *my_get_symbol(DEVICE *device, uint32_t addr)
 {
        symbol_t *first_symbol = NULL;
-       
+
        if(device != NULL) {
                DEBUGGER *debugger = (DEBUGGER *)device->get_debugger();
                if(debugger != NULL) {
@@ -135,7 +135,7 @@ const _TCHAR *my_get_symbol(DEVICE *device, uint32_t addr)
 const _TCHAR *my_get_value_or_symbol(DEVICE *device, const _TCHAR *format, uint32_t addr)
 {
        symbol_t *first_symbol = NULL;
-       
+
        if(device != NULL) {
                DEBUGGER *debugger = (DEBUGGER *)device->get_debugger();
                if(debugger != NULL) {
@@ -148,7 +148,7 @@ const _TCHAR *my_get_value_or_symbol(DEVICE *device, const _TCHAR *format, uint3
 const _TCHAR *my_get_value_and_symbol(DEVICE *device, const _TCHAR *format, uint32_t addr)
 {
        symbol_t *first_symbol = NULL;
-       
+
        if(device != NULL) {
                DEBUGGER *debugger = (DEBUGGER *)device->get_debugger();
                if(debugger != NULL) {
@@ -178,9 +178,9 @@ void show_break_reason(OSD_BASE *osd, DEVICE *cpu, DEVICE *target, bool hide_bp)
 {
        DEBUGGER *cpu_debugger = (DEBUGGER *)cpu->get_debugger();
        DEBUGGER *target_debugger = (DEBUGGER *)target->get_debugger();
-       
+
        osd->set_console_text_attribute(OSD_CONSOLE_RED | OSD_CONSOLE_INTENSITY);
-       
+
        if(cpu_debugger != NULL) {
                if(cpu_debugger->bp.hit && !hide_bp) {
                        my_printf(osd, _T("breaked at %s: breakpoint %s was hit\n"),
@@ -268,7 +268,7 @@ void* debugger_thread(void *lpx)
 {
        volatile debugger_thread_t *p = (debugger_thread_t *)lpx;
        p->running = true;
-       
+
        // initialize console
        std::list<std::string> helplist;
        std::list<std::string> complist;
@@ -301,16 +301,16 @@ void* debugger_thread(void *lpx)
        helplist.push_back("[{R,W,I,O}]B{C,D,E} {*,<list>} - clear/disable/enable breakpoint(s)");
        helplist.push_back("[{R,W,I,O}]BL - list breakpoints");
        helplist.push_back("[{R,W,I,O}]CP <address/port> [<mask>] - set checkpoint (don't break)");
-                               
+
        helplist.push_back("G - go (press esc key to break)");
        helplist.push_back("G <address> - go and break at address (ignore breakpoints)");
        helplist.push_back("P - trace one opcode (step over, ignore breakpoints)");
        helplist.push_back("T [<count>] - trace (step in)");
        helplist.push_back("Q - quit");
-                               
+
        helplist.push_back("> <filename> - output logfile");
        helplist.push_back("< <filename> - input commands from file");
-                               
+
        helplist.push_back("! reset [all/cpu/target] - reset");
        helplist.push_back("! key <code> [<msec>] - press key");
        helplist.push_back("! device - enumerate debugger available device");
@@ -337,7 +337,7 @@ void* debugger_thread(void *lpx)
                helplist.push_back("! mount_cmt <drive> - mount cassette tape\n");
                helplist.push_back("! unmount_cmt <drive> - unmount cassette tape\n");
        }
-       
+
        helplist.push_back("!! <remark> - do nothing");
 
        helplist.push_back("<value> - hexa, decimal(%%d), ascii('a')");
@@ -414,9 +414,9 @@ void* debugger_thread(void *lpx)
 
        _TCHAR buffer[8192];
        bool cp932 = (p->osd->get_console_code_page() == 932);
-       
+
        p->osd->open_console(120, 30, (_TCHAR *)create_string(_T("Debugger - %s"), _T(DEVICE_NAME)));
-       
+
        // break cpu
        DEVICE *cpu = p->vm->get_cpu(p->cpu_index);
        DEBUGGER *cpu_debugger = (DEBUGGER *)cpu->get_debugger();
@@ -438,43 +438,45 @@ void* debugger_thread(void *lpx)
                }
                p->osd->sleep(10);
        }
-       
+
+       p->osd->set_console_text_attribute(OSD_CONSOLE_GREEN | /*OSD_CONSOLE_BLUE |*/ OSD_CONSOLE_INTENSITY);
+       my_printf(p->osd, _T("enter '?' to show the list of commands\n"));
        uint32_t dump_addr = 0;
        uint32_t dasm_addr = cpu->get_next_pc();
-       
+
        p->osd->set_console_text_attribute(OSD_CONSOLE_RED | OSD_CONSOLE_GREEN | OSD_CONSOLE_BLUE | OSD_CONSOLE_INTENSITY);
        if(cpu->get_debug_regs_info(buffer, array_length(buffer))) {
                my_printf(p->osd, _T("%s\n"), buffer);
        }
-       
+
        p->osd->set_console_text_attribute(OSD_CONSOLE_RED | OSD_CONSOLE_INTENSITY);
        my_printf(p->osd, _T("breaked at %s\n"), my_get_value_and_symbol(cpu, _T("%08X"), cpu->get_next_pc()));
-       
+
        p->osd->set_console_text_attribute(OSD_CONSOLE_GREEN | OSD_CONSOLE_BLUE | OSD_CONSOLE_INTENSITY);
        cpu->debug_dasm(cpu->get_next_pc(), buffer, array_length(buffer));
        my_printf(p->osd, _T("next\t%s  %s\n"), my_get_value_and_symbol(cpu, _T("%08X"), cpu->get_next_pc()), buffer);
        p->osd->set_console_text_attribute(OSD_CONSOLE_RED | OSD_CONSOLE_GREEN | OSD_CONSOLE_BLUE | OSD_CONSOLE_INTENSITY);
-       
+
        // initialize files
        logfile = NULL;
        cmdfile = NULL;
-       
+
        _TCHAR command[MAX_COMMAND_LENGTH + 1];
        _TCHAR prev_command[MAX_COMMAND_LENGTH + 1];
-       
+
        memset(prev_command, 0, sizeof(prev_command));
 
        while(!p->request_terminate) {
                p->emu->draw_screen();
-               
+
                my_printf(p->osd, _T("- "));
-               
+
                // get command
                _TCHAR ir[16 + 2];
                int enter_ptr = 0;
                int history_ptr = 0;
                bool enter_done = false;
-               
+
                while(!p->request_terminate && !enter_done) {
                        if(cmdfile != NULL && cmdfile->IsOpened()) {
                                if(cmdfile->Fgetts(command, array_length(command)) != NULL) {
@@ -493,7 +495,7 @@ void* debugger_thread(void *lpx)
                        } else {
                                memset(ir, 0, sizeof(ir));
                                int count = p->osd->read_console_input(ir, 16);
-                               
+
                                for(int i = 0; i < count; i++) {
                                        if(ir[i] == 0x08) {
                                                if(enter_ptr > 0) {
@@ -566,12 +568,12 @@ void* debugger_thread(void *lpx)
                                p->osd->sleep(10);
                        }
                }
-               
+
                // process command
                if(!p->request_terminate && enter_done) {
                        _TCHAR *params[32], *token = NULL, *context = NULL;
                        int num = 0;
-               
+
                        for(int i = 0; i < ((sizeof(params) / sizeof(_TCHAR *))); i++) {
                                params[i] = (_TCHAR *)(_T(""));
                        }
@@ -588,13 +590,13 @@ void* debugger_thread(void *lpx)
                                                start_addr = my_hexatoi(target, params[1]);
                                        }
                                        start_addr %= target->get_debug_data_addr_space();
-                                       
+
                                        uint32_t end_addr = start_addr + 8 * 16 - 1;
                                        if(num == 3) {
                                                end_addr = my_hexatoi(target, params[2]);
                                        }
                                        end_addr %= target->get_debug_data_addr_space();
-                                       
+
                                        if(start_addr > end_addr) {
                                                end_addr = (uint32_t)(target->get_debug_data_addr_space() - 1);
                                        }
@@ -829,7 +831,7 @@ void* debugger_thread(void *lpx)
                                                struct tm *timedat;
                                                time_t nowtime;
                                                struct timeval tv;
-                                                               
+
                                                nowtime = time(NULL);
                                                gettimeofday(&tv, NULL);
                                                timedat = localtime(&nowtime);
@@ -880,7 +882,7 @@ void* debugger_thread(void *lpx)
                                        int steps = 128;
                                        int xnum = 1;
                                        bool logging = false;
-                                       
+
                                        if(num >= 2) {
                                                if((strcasecmp(params[xnum], "0") == 0)) {
                                                        steps = MAX_CPU_TRACE - 1; // TBD
@@ -892,7 +894,7 @@ void* debugger_thread(void *lpx)
                                                }
                                        }
                                        FILEIO* log_fio = NULL;
-                                       if(steps > 0) {  // Workaround for gcc-9. 
+                                       if(steps > 0) {  // Workaround for gcc-9.
                                                _TCHAR log_path[_MAX_PATH];
                                                if(xnum < num) {
                                                        my_tcscpy_s(log_path, _MAX_PATH, create_absolute_path(params[xnum]));
@@ -900,7 +902,7 @@ void* debugger_thread(void *lpx)
                                                }
                                                if(logging) {
                                                        log_fio = new FILEIO();
-                                                       if(!(log_fio->Fopen((const _TCHAR*)log_path, FILEIO_WRITE_APPEND_ASCII))) { // Failed to open 
+                                                       if(!(log_fio->Fopen((const _TCHAR*)log_path, FILEIO_WRITE_APPEND_ASCII))) { // Failed to open
                                                                delete log_fio;
                                                                log_fio = NULL;
                                                                logging = false;
@@ -912,7 +914,7 @@ void* debugger_thread(void *lpx)
                                                                        struct tm *timedat;
                                                                        time_t nowtime;
                                                                        struct timeval tv;
-                                                               
+
                                                                        nowtime = time(NULL);
                                                                        gettimeofday(&tv, NULL);
                                                                        timedat = localtime(&nowtime);
@@ -978,7 +980,7 @@ void* debugger_thread(void *lpx)
                                                                }
                                                                my_sprintf_s(tmps2, sizeof(tmps2), _T("  %s"), buffer);
                                                                strncat(tmps, tmps2, sizeof(tmps) - 1);
-                                                       
+
                                                                if(target_debugger->cpu_trace_exp_map[index]) {
                                                                        my_sprintf_s(tmps2, sizeof(tmps2), _T("  <== EXCEPTION 0x%08X\n"), target_debugger->cpu_trace_exp[index]);
                                                                } else {
@@ -1379,7 +1381,7 @@ RESTART_GO:
                                        cpu_debugger->exception_pc = cpu->get_pc();
                                        cpu_debugger->now_going = true;
                                        cpu_debugger->now_suspended = false;
-#if defined(_MSC_VER)                                     
+#if defined(_MSC_VER)
                                        while(!p->request_terminate && !cpu_debugger->now_suspended && !(cpu_debugger->exception_happened && cpu_debugger->stop_on_exception)) {
                                                if(p->osd->is_console_key_pressed(VK_ESCAPE)) {
                                                        break;
@@ -1394,7 +1396,7 @@ RESTART_GO:
                                                }
                                                p->osd->sleep(10);
                                        }
-#endif                                    
+#endif
                                        // break cpu
                                        cpu_debugger->now_going = false;
                                        wait_count = 0;
@@ -1408,7 +1410,7 @@ RESTART_GO:
                                        if(target == cpu) {
                                                dasm_addr = cpu->get_next_pc();
                                        }
-                                       
+
                                        p->osd->set_console_text_attribute(OSD_CONSOLE_GREEN | OSD_CONSOLE_BLUE | OSD_CONSOLE_INTENSITY);
                                        cpu->debug_dasm(cpu->get_pc(), buffer, array_length(buffer));
                                        if(cpu_debugger->exception_happened) {
@@ -1416,14 +1418,14 @@ RESTART_GO:
                                        }
                                        cpu_debugger->exception_happened = false;
                                        cpu_debugger->exception_code = 0;
-                                               
+
                                        my_printf(p->osd, _T("done\t%s  %s\n"), my_get_value_and_symbol(cpu, _T("%08X"), cpu->get_pc()), buffer);
-                                       
+
                                        p->osd->set_console_text_attribute(OSD_CONSOLE_RED | OSD_CONSOLE_GREEN | OSD_CONSOLE_BLUE | OSD_CONSOLE_INTENSITY);
                                        if(cpu->get_debug_regs_info(buffer, array_length(buffer))) {
                                                my_printf(p->osd, _T("%s\n"), buffer);
                                        }
-                                       
+
                                        if(target != cpu) {
                                                p->osd->set_console_text_attribute(OSD_CONSOLE_GREEN | OSD_CONSOLE_INTENSITY);
                                                if(target->debug_dasm(target->get_next_pc(), buffer, array_length(buffer)) != 0) {
@@ -1433,7 +1435,7 @@ RESTART_GO:
                                                        my_printf(p->osd, _T("%s\n"), buffer);
                                                }
                                        }
-                                       
+
                                        if(cpu_debugger->hit()) {
                                                show_break_reason(p->osd, cpu, target, (_tcsicmp(params[0], _T("P")) == 0));
                                                bool restart = cpu_debugger->restartable();
@@ -1477,19 +1479,19 @@ RESTART_GO:
                                                if(target == cpu) {
                                                        dasm_addr = cpu->get_next_pc();
                                                }
-                                               
+
                                                if(cpu_debugger->exception_happened) {
                                                        my_printf(p->osd, _T("**EXCEPTION #%08X happened at %08X\n"), cpu_debugger->exception_code, cpu_debugger->exception_pc);
                                                }
                                                p->osd->set_console_text_attribute(OSD_CONSOLE_GREEN | OSD_CONSOLE_BLUE | OSD_CONSOLE_INTENSITY);
                                                cpu->debug_dasm(cpu->get_pc(), buffer, array_length(buffer));
                                                my_printf(p->osd, _T("done\t%s  %s\n"), my_get_value_and_symbol(cpu, _T("%08X"), cpu->get_pc()), buffer);
-                                               
+
                                                p->osd->set_console_text_attribute(OSD_CONSOLE_RED | OSD_CONSOLE_GREEN | OSD_CONSOLE_BLUE | OSD_CONSOLE_INTENSITY);
                                                if(cpu->get_debug_regs_info(buffer, array_length(buffer))) {
                                                        my_printf(p->osd, _T("%s\n"), buffer);
                                                }
-                                               
+
                                                if(target != cpu) {
                                                        p->osd->set_console_text_attribute(OSD_CONSOLE_GREEN | OSD_CONSOLE_INTENSITY);
                                                        if(target->debug_dasm(target->get_next_pc(), buffer, array_length(buffer)) != 0) {
@@ -1499,7 +1501,7 @@ RESTART_GO:
                                                                my_printf(p->osd, _T("%s\n"), buffer);
                                                        }
                                                }
-                                               
+
                                                if(cpu_debugger->hit()) {
                                                        show_break_reason(p->osd, cpu, target, false);
                                                        bool restart = cpu_debugger->restartable();
@@ -1682,15 +1684,15 @@ RESTART_GO:
                                                                }
                                                                dump_addr = 0;
                                                                dasm_addr = cpu->get_next_pc();
-                                                               
+
                                                                p->osd->set_console_text_attribute(OSD_CONSOLE_RED | OSD_CONSOLE_GREEN | OSD_CONSOLE_BLUE | OSD_CONSOLE_INTENSITY);
                                                                if(cpu->get_debug_regs_info(buffer, array_length(buffer))) {
                                                                        my_printf(p->osd, _T("%s\n"), buffer);
                                                                }
-                                                               
+
                                                                p->osd->set_console_text_attribute(OSD_CONSOLE_RED | OSD_CONSOLE_INTENSITY);
                                                                my_printf(p->osd, _T("breaked at %s\n"), my_get_value_and_symbol(cpu, _T("%08X"), cpu->get_next_pc()));
-                                                               
+
                                                                p->osd->set_console_text_attribute(OSD_CONSOLE_GREEN | OSD_CONSOLE_BLUE | OSD_CONSOLE_INTENSITY);
                                                                cpu->debug_dasm(cpu->get_next_pc(), buffer, array_length(buffer));
                                                                my_printf(p->osd, _T("next\t%s  %s\n"), my_get_value_and_symbol(cpu, _T("%08X"), cpu->get_next_pc()), buffer);
@@ -1712,7 +1714,7 @@ RESTART_GO:
                                                        cpu_debugger->store_break_points();
                                                        cpu_debugger->now_going = true;
                                                        cpu_debugger->now_suspended = false;
-                                                       
+
                                                        // wait until save/load state is done at top of next frame
                                                        wait_count = 0;
                                                        while(!p->request_terminate && (p->emu->request_save_state != -1 || p->emu->request_load_state != -1)) {
@@ -1751,16 +1753,16 @@ RESTART_GO:
                                                                dasm_addr = cpu->get_next_pc();
                                                        }
                                                        cpu_debugger->restore_break_points();
-                                                       
+
                                                        p->osd->set_console_text_attribute(OSD_CONSOLE_GREEN | OSD_CONSOLE_BLUE | OSD_CONSOLE_INTENSITY);
                                                        cpu->debug_dasm(cpu->get_pc(), buffer, array_length(buffer));
                                                        my_printf(p->osd, _T("done\t%s  %s\n"), my_get_value_and_symbol(cpu, _T("%08X"), cpu->get_pc()), buffer);
-                                                       
+
                                                        p->osd->set_console_text_attribute(OSD_CONSOLE_RED | OSD_CONSOLE_GREEN | OSD_CONSOLE_BLUE | OSD_CONSOLE_INTENSITY);
                                                        if(cpu->get_debug_regs_info(buffer, array_length(buffer))) {
                                                                my_printf(p->osd, _T("%s\n"), buffer);
                                                        }
-                                                       
+
                                                        if(target != cpu) {
                                                                p->osd->set_console_text_attribute(OSD_CONSOLE_GREEN | OSD_CONSOLE_INTENSITY);
                                                                if(target->debug_dasm(target->get_next_pc(), buffer, array_length(buffer)) != 0) {
@@ -1770,7 +1772,7 @@ RESTART_GO:
                                                                        my_printf(p->osd, _T("%s\n"), buffer);
                                                                }
                                                        }
-                                                       
+
                                                        p->osd->set_console_text_attribute(OSD_CONSOLE_RED | OSD_CONSOLE_INTENSITY);
                                                        my_printf(p->osd, _T("breaked at %s\n"), my_get_value_and_symbol(cpu, _T("%08X"), cpu->get_next_pc()));
                                                        p->osd->set_console_text_attribute(OSD_CONSOLE_GREEN | OSD_CONSOLE_BLUE | OSD_CONSOLE_INTENSITY);
@@ -1887,7 +1889,7 @@ RESTART_GO:
                        }
                }
        }
-       
+
        // stop debugger
        try {
                if(target_debugger != NULL) {
@@ -1896,7 +1898,7 @@ RESTART_GO:
                cpu_debugger->now_debugging = cpu_debugger->now_going = cpu_debugger->now_suspended = cpu_debugger->now_waiting = false;
        } catch(...) {
        }
-       
+
        // release files
        if(logfile != NULL) {
                if(logfile->IsOpened()) {
@@ -1912,10 +1914,10 @@ RESTART_GO:
                delete cmdfile;
                cmdfile = NULL;
        }
-       
+
        // release console
        p->osd->close_console();
-       
+
        p->running = false;
 #ifdef _MSC_VER
        _endthreadex(0);
@@ -1971,7 +1973,7 @@ void EMU::open_debugger(int cpu_index)
 
 void EMU::close_debugger(int cpu_index)
 {
-       
+
        if(now_debugging) {
                if(debugger_thread_param.running) {
                        debugger_thread_param.request_terminate = true;
@@ -2003,4 +2005,3 @@ bool EMU::is_debugger_enabled(int cpu_index)
        return (vm->get_cpu(cpu_index) != NULL && vm->get_cpu(cpu_index)->get_debugger() != NULL);
 }
 #endif
-
index f1c16d5..1f7da3c 100644 (file)
@@ -1,5 +1,5 @@
 message("* qt/osd")
-SET(THIS_LIB_VERSION 9.4.0)
+SET(THIS_LIB_VERSION 9.5.0)
 
 set(s_qt_osd_headers
        osd_base.h
index 2db6fcd..e206887 100644 (file)
@@ -1,6 +1,6 @@
 message("* qt/avio")
 
-SET(THIS_LIB_VERSION 7.6.2)
+SET(THIS_LIB_VERSION 7.7.0)
 set(s_qt_avio_headers
        csp_avio_basic.h
        movie_saver.h
index 477c56b..9402745 100644 (file)
@@ -1,6 +1,6 @@
 message("* qt/emuutils")
 
-SET(THIS_LIB_VERSION 7.12.0)
+SET(THIS_LIB_VERSION 7.13.0)
 
 set(s_qt_emuutils_headers
        ../gui/csp_logger.h
index b7e3e11..1372dc5 100644 (file)
@@ -1,6 +1,6 @@
 message("* qt/gui")
 
-set(THIS_LIB_VERSION 8.9.0)
+set(THIS_LIB_VERSION 8.10.0)
 
 set(s_qt_gui_headers
          qt_dialogs.h
index 2a85940..69293f3 100644 (file)
@@ -1,6 +1,6 @@
 message("* vm/common_vm")
 
-SET(THIS_LIB_VERSION 7.6.6)
+SET(THIS_LIB_VERSION 7.7.0)
 
 #include(cotire)
 set(s_vm_common_vm_srcs
@@ -181,7 +181,6 @@ set(s_vm_common_vm_srcs
     ../np21/i386c/ia32/instructions/sse/sse.cpp
     ../np21/i386c/ia32/instructions/sse2/sse2.cpp
     ../np21/i386c/ia32/instructions/sse3/sse3.cpp
-#      ../libcpu_newdev/device.cpp
 )
 
 #set_directory_properties(PROPERTIES
index a364331..053de69 100644 (file)
@@ -606,13 +606,13 @@ void DEVICE::write_signals(outputs_t *items, uint32_t data)
 
 void DEVICE::update_signal_mask(outputs_t *items, DEVICE *device, uint32_t mask)
 {
-       if(items == NULL) return;
+       __UNLIKELY_IF(items == NULL) return;
        int c = items->count;
-       if(c <= 0) return;
-       if(c >= MAX_OUTPUT) c = MAX_OUTPUT - 1;
+       __UNLIKELY_IF(c <= 0) return;
+       __LIKELY_IF(c >= MAX_OUTPUT) c = MAX_OUTPUT - 1;
        // if (ARG:device == NULL) apply to all devices.
        for(int i = 0; i < c; i++) {
-               if((device == NULL) || (device == items->item[i].device)) {
+               __UNLIKELY_IF((device == NULL) || (device == items->item[i].device)) {
                        items->item[i].mask = mask;
                }
        }
@@ -726,7 +726,7 @@ bool DEVICE::bios_ret_z80(uint16_t PC, pair32_t* af, pair32_t* bc, pair32_t* de,
 
 void DEVICE::clear_sound_in_source(int bank)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        event_manager->clear_sound_in_source(bank);
@@ -737,20 +737,20 @@ void DEVICE::clear_sound_in_source(int bank)
 // this function may be before (or after) initialize().
 int DEVICE::add_sound_in_source(int rate, int samples, int channels)
 {
-       if(event_manager == NULL) return -1;
+       __UNLIKELY_IF(event_manager == NULL) return -1;
        return event_manager->add_sound_in_source(rate, samples, channels);
 }
 
 // this function may be before (or after) initialize().
 int DEVICE::release_sound_in_source(int bank)
 {
-       if(event_manager == NULL) return -1;
+       __UNLIKELY_IF(event_manager == NULL) return -1;
        return event_manager->release_sound_in_source(bank);
 }
 
 bool DEVICE::is_sound_in_source_exists(int bank)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        return event_manager->is_sound_in_source_exists(bank);
@@ -758,7 +758,7 @@ bool DEVICE::is_sound_in_source_exists(int bank)
 
 int DEVICE::increment_sound_in_passed_data(int bank, double passed_usec)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                return 0;
        }
        return event_manager->increment_sound_in_passed_data(bank, passed_usec);
@@ -766,7 +766,7 @@ int DEVICE::increment_sound_in_passed_data(int bank, double passed_usec)
 
 int DEVICE::get_sound_in_buffers_count()
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        return event_manager->get_sound_in_buffers_count();
@@ -774,7 +774,7 @@ int DEVICE::get_sound_in_buffers_count()
 
 int DEVICE::get_sound_in_samples(int bank)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        return event_manager->get_sound_in_samples(bank);
@@ -782,7 +782,7 @@ int DEVICE::get_sound_in_samples(int bank)
 
 int DEVICE::get_sound_in_rate(int bank)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        return event_manager->get_sound_in_rate(bank);
@@ -790,7 +790,7 @@ int DEVICE::get_sound_in_rate(int bank)
 
 int DEVICE::get_sound_in_channels(int bank)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        return event_manager->get_sound_in_channels(bank);
@@ -799,13 +799,13 @@ int DEVICE::get_sound_in_channels(int bank)
 // this function may be before (or after) initialize().
 int16_t* DEVICE::get_sound_in_buf_ptr(int bank)
 {
-       if(event_manager == NULL) return NULL;
+       __UNLIKELY_IF(event_manager == NULL) return NULL;
        return event_manager->get_sound_in_buf_ptr(bank);
 }
 
 int DEVICE::write_sound_in_buffer(int bank, int32_t* src, int samples)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        return event_manager->write_sound_in_buffer(bank, src, samples);
@@ -815,13 +815,13 @@ int DEVICE::write_sound_in_buffer(int bank, int32_t* src, int samples)
 // this function may be before (or after) initialize().
 int DEVICE::get_sound_in_latest_data(int bank, int32_t* dst, int expect_channels)
 {
-       if(event_manager == NULL) return 0;
+       __UNLIKELY_IF(event_manager == NULL) return 0;
        return event_manager->get_sound_in_latest_data(bank, dst, expect_channels);
 }
 
 int DEVICE::get_sound_in_data(int bank, int32_t* dst, int expect_samples, int expect_rate, int expect_channels)
 {
-       if(event_manager == NULL) return -1;
+       __UNLIKELY_IF(event_manager == NULL) return -1;
        return event_manager->get_sound_in_data(bank, dst, expect_samples, expect_rate, expect_channels);
 }
 
@@ -835,7 +835,7 @@ void DEVICE::set_low_pass_filter_freq(int freq, double quality)
 
 int DEVICE::get_event_manager_id()
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        return event_manager->this_device_id;
@@ -843,7 +843,7 @@ int DEVICE::get_event_manager_id()
 
 uint32_t DEVICE::get_event_clocks()
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        return event_manager->get_event_clocks();
@@ -851,7 +851,7 @@ uint32_t DEVICE::get_event_clocks()
 
 bool DEVICE::is_primary_cpu(DEVICE* device)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        return event_manager->is_primary_cpu(device);
@@ -859,22 +859,23 @@ bool DEVICE::is_primary_cpu(DEVICE* device)
 
 uint32_t DEVICE::get_cpu_clocks(DEVICE* device)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        return event_manager->get_cpu_clocks(device);
 }
-void DEVICE::update_extra_event(int clock)
+
+void DEVICE::update_event_in_opecode(int clock)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
-       event_manager->update_extra_event(clock);
+       event_manager->update_event_in_opecode(clock);
 }
 
 void DEVICE::register_event(DEVICE* device, int event_id, double usec, bool loop, int* register_id)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        event_manager->register_event(device, event_id, usec, loop, register_id);
@@ -882,7 +883,7 @@ void DEVICE::register_event(DEVICE* device, int event_id, double usec, bool loop
 
 void DEVICE::register_event_by_clock(DEVICE* device, int event_id, uint64_t clock, bool loop, int* register_id)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        event_manager->register_event_by_clock(device, event_id, clock, loop, register_id);
@@ -890,7 +891,7 @@ void DEVICE::register_event_by_clock(DEVICE* device, int event_id, uint64_t cloc
 
 void DEVICE::cancel_event(DEVICE* device, int register_id)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        event_manager->cancel_event(device, register_id);
@@ -899,7 +900,7 @@ void DEVICE::cancel_event(DEVICE* device, int register_id)
 // Clear and DE-Register EVENT at slot evid.
 void DEVICE::clear_event(DEVICE* dev, int& evid)
 {
-       if(evid > -1) {
+       __LIKELY_IF(evid > -1) {
                cancel_event(dev, evid);
        }
        evid = -1;
@@ -921,27 +922,27 @@ void DEVICE::force_register_event_by_clock(DEVICE* dev, int event_num, uint64_t
 // Register a EVENT to evid , if evid slot isn't used.
 void DEVICE::check_and_update_event(DEVICE* dev, int event_num, double usec, bool loop, int& evid)
 {
-       if(evid > -1) return;
+       __UNLIKELY_IF(evid > -1) return;
        register_event(dev, event_num, usec, loop, &evid);
 }
 
 void DEVICE::check_and_update_event_by_clock(DEVICE* dev, int event_num, uint64_t clock, bool loop, int& evid)
 {
-       if(evid > -1) return;
+       __UNLIKELY_IF(evid > -1) return;
        register_event_by_clock(dev, event_num, clock, loop, &evid);
 }
 
 
 void DEVICE::register_frame_event(DEVICE* device)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        event_manager->register_frame_event(device);
 }
 void DEVICE::register_vline_event(DEVICE* device)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        event_manager->register_vline_event(device);
@@ -949,7 +950,7 @@ void DEVICE::register_vline_event(DEVICE* device)
 
 uint32_t DEVICE::get_event_remaining_clock(int register_id)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        return event_manager->get_event_remaining_clock(register_id);
@@ -957,7 +958,7 @@ uint32_t DEVICE::get_event_remaining_clock(int register_id)
 
 double DEVICE::get_event_remaining_usec(int register_id)
 {
-       if(event_manager == NULL) {
+       __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
        return event_manager->get_event_remaining_usec(register_id);
@@ -1095,7 +1096,7 @@ void DEVICE::set_realtime_render(DEVICE *device, bool flag)
        __UNLIKELY_IF(event_manager == NULL) {
                event_manager = vm->first_device->next_device;
        }
-       __UNLIKELY_IF(device != event_manager) event_manager->set_realtime_render(device, flag);
+       __LIKELY_IF(device != event_manager) event_manager->set_realtime_render(device, flag);
 }
 
 void DEVICE::update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame)
@@ -1142,7 +1143,7 @@ void DEVICE::get_volume(int ch, int &decibel_l, int &decibel_r)
 
 void DEVICE::set_device_name(const _TCHAR *format, ...)
 {
-       if(format != NULL) {
+       __LIKELY_IF(format != NULL) {
                va_list ap;
                _TCHAR buffer[1024];
 
@@ -1181,7 +1182,7 @@ void DEVICE::out_debug_log(const char *fmt, ...)
 
 void DEVICE::out_debug_log_with_switch(bool logging, const char *fmt, ...)
 {
-       if(!(logging)) return;
+       __UNLIKELY_IF(!(logging)) return;
 #if defined(_USE_QT)
        __UNLIKELY_IF(osd == nullptr) return;
        char strbuf[4096] = {0};
index fce773a..8b78000 100644 (file)
@@ -63,12 +63,12 @@ public:
         *  destructor might cause undefined behavior [-Wdelete-non-virtual-dtor]".
         */
        ~DEVICE(void);
-       
+
        /*!
         * @brief Initialize a DEVICE.
         * @note Initializing VM must be after initializing OSD.
         * @note You may call DEVICE::initialize() FOO::initialize() of inherited class.
-        */ 
+        */
        virtual void initialize();
        /*!
         * @brief De-Allocate resources before DESTRUCTION this class.
@@ -77,7 +77,7 @@ public:
        virtual void release();
        //!< Sound input functions
        /*!
-        * @brief clear a temporaly sound buffer to zero. 
+        * @brief clear a temporaly sound buffer to zero.
         * @param bank bank number of temporaly sound buffer.
         */
        virtual void clear_sound_in_source(int bank);
@@ -99,7 +99,7 @@ public:
         * @note this function may be before (or after) initialize().
         */
        virtual int release_sound_in_source(int bank);
-       
+
        /*!
         * @brief check whether a temporaly sound buffer exists.
         * @param bank number wish to check.
@@ -241,7 +241,7 @@ public:
         * @note normally returns true when saving.
         */
        virtual bool process_state(FILEIO* state_fio, bool loading);
-       
+
        /*!
         * @brief get linear address from segment:offset model.
         * @param segment number of segment.
@@ -254,7 +254,7 @@ public:
         * @deprecated this function will not use from bios
         */
        virtual uint32_t __FASTCALL translate_address(int segment, uint32_t offset);
-       
+
        //<! memory bus
        /*!
         * @brief write a 8bit width data to memory .
@@ -420,7 +420,7 @@ public:
         * @return read value.
         */
        virtual uint32_t __FASTCALL read_dma_data32w(uint32_t addr, int* wait);
-       
+
        //<! i/o bus
        /*!
         * @brief write 8bit width data to I/O bus.
@@ -578,7 +578,7 @@ public:
         * @return read value from I/O.
         */
        virtual uint32_t __FASTCALL read_dma_io32w(uint32_t addr, int* wait);
-       
+
        // memory mapped i/o
        /*!
          @brief write 8bit width data to this device's MMIO (or MEMORY).
@@ -670,7 +670,7 @@ public:
          @note This method is called from another device, normally MEMORY BUS.
        */
        virtual uint32_t __FASTCALL read_memory_mapped_io32w(uint32_t addr, int* wait);
-       
+
        //<! device to device
        /*!
         * @struct output_t
@@ -682,7 +682,7 @@ public:
                uint32_t mask;  //<! value mask of this signal
                int shift;              //<! shifting value to write.
        } output_t;
-       
+
        /*!
         * @struct outputs_t
         * @brief multiple output port.
@@ -696,7 +696,7 @@ public:
         * @param items pointer of multiple output port.
         * @note must call before using a multiple output port.
         * @note items must be pointer, not be multiple output port.
-        */ 
+        */
        virtual void initialize_output_signals(outputs_t *items);
        /*!
         * @brief register a port to multiple output port
@@ -749,7 +749,7 @@ public:
         * @retval 0 default value.
         */
        virtual uint32_t __FASTCALL read_signal(int ch);
-       
+
        //<! z80 daisy chain
        /*!
         * @brief set target device for INTR signal
@@ -759,25 +759,25 @@ public:
         */
        virtual void set_context_intr(DEVICE* device, uint32_t bit);
        /*!
-        * @brief register child (slave) device to this device. 
+        * @brief register child (slave) device to this device.
         * @param device pointer of child device.
         */
        virtual void set_context_child(DEVICE* device);
-       
+
        /*!
-        * @brief get  child (slave) device of this device.     
+        * @brief get  child (slave) device of this device.
         * @return pointer of child device.
         * @retval nullptr child not exists.
         * @retval NULL child not exists.
         */
        virtual DEVICE *get_context_child();
-       
+
        /*!
         * @brief send interrupt (IEI) signal from device to device
         * @param val interrupt status value
         */
        virtual void __FASTCALL set_intr_iei(bool val);
-       
+
        /*!
         * @brief send interrupt signal from device to cpu
         * @param line signal value
@@ -785,7 +785,7 @@ public:
         * @param bit interrupt bit to update.
         */
        virtual void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit);
-       
+
        // interrupt cpu to device
        /*!
          @brief get acknowledge value from this device.
@@ -806,12 +806,12 @@ public:
          @brief notify EI signal to this device from CPU.
         */
        virtual void notify_intr_ei();
-       
+
        /*!
          @brief do a DMA transfer cycle.
         */
        virtual void __FASTCALL do_dma();
-       
+
        //<! cpu
        /*!
          @brief run instruction(s) of CPU
@@ -827,7 +827,7 @@ public:
         */
        virtual void __FASTCALL set_extra_clock(int clock);
        /*!
-         @brief get extra clocks 
+         @brief get extra clocks
          @return extra clocks
          @retval 0 default value.
         */
@@ -845,7 +845,7 @@ public:
         * @note normally this value contains current instruction address.
         */
        virtual uint32_t get_next_pc();
-       
+
        //<! bios
        /*!
         * @brief hook of pseudo bios for i86 (16bit) variants
@@ -861,7 +861,7 @@ public:
        virtual bool bios_call_far_i86(uint32_t PC, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles);
        /*!
         * @brief hook of INTxx pseudo bios for i86 (16bit) variants
-        * @param intnum number of software interrupt 
+        * @param intnum number of software interrupt
         * @param regs array of general purpose registes
         * @param sregs array of segment registers
         * @param ZeroFlag pointer to get ZeroFlag
@@ -885,7 +885,7 @@ public:
        virtual bool bios_call_far_ia32(uint32_t PC, uint32_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles);
        /*!
         * @brief hook of INTxx pseudo bios for i386 (32bit) variants
-        * @param intnum number of software interrupt 
+        * @param intnum number of software interrupt
         * @param regs array of general purpose registes
         * @param sregs array of segment registers
         * @param ZeroFlag pointer to get ZeroFlag
@@ -916,9 +916,9 @@ public:
        */
        virtual bool __FASTCALL address_translate_for_bios(int space, int intention, uint64_t &taddress);
        // misc
-   
+
        // event manager
-       DEVICE* event_manager; //<! event manager for this device (normally EVENT::). 
+       DEVICE* event_manager; //<! event manager for this device (normally EVENT::).
        /*!
         * @brief set event manager of this device
         * @param device pointer if event manager.
@@ -947,7 +947,7 @@ public:
         * @brief get cpu clocks of target device
         * @param device target device
         * @return cpu clocks value (by HZ).
-        * @retval CPU_CLOCKS when target is *not* CPU 
+        * @retval CPU_CLOCKS when target is *not* CPU
         */
        virtual uint32_t __FASTCALL get_cpu_clocks(DEVICE* device);
        /*!
@@ -955,7 +955,7 @@ public:
         * @param clock clocks period for primary CPU.
         * @note this is called from primary cpu while running one opecode
        */
-       virtual void __FASTCALL update_extra_event(int clock);
+       virtual void __FASTCALL update_event_in_opecode(int clock);
        /*!
         * @brief register a event of device to event manager by microseconds.
         * @param device target device (normally this)
@@ -1040,14 +1040,14 @@ public:
         */
        virtual void register_vline_event(DEVICE* device);
        /*!
-         @brief inspect scheduled remain clocks until happened a event. 
+         @brief inspect scheduled remain clocks until happened a event.
          @param register_id event id what wish to check remain.
          @return remain clock count until happen this event.
          @retval 0 already happened or evenr_id dont' exists.
         */
        virtual uint32_t __FASTCALL get_event_remaining_clock(int register_id);
        /*!
-         @brief inspect scheduled remain uSecs until happened a event. 
+         @brief inspect scheduled remain uSecs until happened a event.
          @param register_id event id what wish to check remain.
          @return remain time by uSecs until happen this event.
          @retval 0.0 already happened or evenr_id dont' exists.
@@ -1140,7 +1140,7 @@ public:
          @brief Force render sound immediately when device's status has changed.
          @note You must call this after you changing registers (or enything).
          @note If has problems, try set_realtime_render.
-         @note See mb8877.cpp and ym2203.cpp. 
+         @note See mb8877.cpp and ym2203.cpp.
          @note -- 20161010 K.O
        */
        virtual void touch_sound(void);
@@ -1166,9 +1166,9 @@ public:
          @param new_frames_per_sec frame rate expect to update.
          @param new_lines_per_frame number of vertical lines expect to update.
          @note any parameters has no means, as of DEVICE definitions.
-       */ 
+       */
        virtual void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame);
-       
+
        //<! event callback
        /*!
          @brief event handler of this device
@@ -1180,19 +1180,19 @@ public:
        /*!
          @brief fixed handler before processing a frame.
          @note must call register_frame_event(this) before using (normally initialize()).
-       */  
+       */
        virtual void event_pre_frame();
        /*!
          @brief fixed handler processing a top of frame.
          @note must call register_frame_event(this) before using (normally initialize()).
-       */  
+       */
        virtual void event_frame();
        /*!
          @brief fixed handler per begin of vertical lines.
          @param v position of vertical line.
          @param clock relative clocks
          @note must call register_vline_event(this) before using (normally initialize()).
-       */  
+       */
        virtual void event_vline(int v, int clock);
        /*!
          @brief fixed handler per a pixel (HSYNC).
@@ -1200,9 +1200,9 @@ public:
          @param h pixel offset position of this vertical line.
          @param clock relative clocks
          @note this still not be used.
-       */  
+       */
        virtual void __FASTCALL event_hsync(int v, int h, int clock);
-       
+
        // sound
        /*!
          @brief render sound samples
@@ -1220,9 +1220,9 @@ public:
          @note +1 equals +0.5dB (same as fmgen)
        */
        virtual void set_volume(int ch, int decibel_l, int decibel_r);
-       
+
        /*!
-         @brief get render sound volume values 
+         @brief get render sound volume values
          @param ch local channel to set volume
          @param decibel_l left volume value by 0.5 decibel
          @param decivel_r right volume value by 0.5 decibel
@@ -1235,25 +1235,6 @@ public:
          @param format name of this device (printf style)
        */
        virtual void set_device_name(const _TCHAR *format, ...);
-/*
-       These functions are used for debugging non-cpu device
-       Insert debugger between standard read/write functions and these functions for checking breakpoints
-
-       void DEVICE::write_data8(uint32_t addr, uint32_t data)
-       {
-               if(debugger != NULL && debugger->now_device_debugging) {
-                       // debugger->mem = this;
-                       // debugger->mem->write_via_debugger_data8(addr, data)
-                       debugger->write_via_debugger_data8(addr, data);
-               } else {
-                       this->write_via_debugger_data8(addr, data);
-               }
-       }
-       void DEVICE::write_via_debugger_data8(uint32_t addr, uint32_t data)
-       {
-               // write memory
-       }
-*/
        /*!
          @brief write 8bit data to memory from debugger.
          @param addr target address to write.
@@ -1374,7 +1355,7 @@ public:
          @param data data to write.
          @param wait pointer of wait result value.
        */
-       virtual void __FASTCALL write_via_debugger_io8w(uint32_t addr, uint32_t data, int* wait); 
+       virtual void __FASTCALL write_via_debugger_io8w(uint32_t addr, uint32_t data, int* wait);
        /*!
          @brief read 8bit data to debugger from I/O bus with wait.
          @param addr target address to read.
@@ -1588,7 +1569,7 @@ public:
         @return results.
         @retval true this device has description of registers.
         @retval false this device doesn't have descpriction of registers.
-       */ 
+       */
        virtual bool get_debug_regs_description(_TCHAR *buffer, size_t buffer_len);
        /*!
          @brief disassemble one instruction.
@@ -1635,10 +1616,10 @@ public:
        const _TCHAR *get_lib_common_vm_version(void);
 
        _TCHAR this_device_name[128];   //<! name of this device
-       
+
        DEVICE* prev_device;    //<! previous device pointer of this device chain
        DEVICE* next_device;    //<! next device pointer of this device chain
-       int this_device_id;             //<! ID of this device 
+       int this_device_id;             //<! ID of this device
 };
 
 #endif
index 8e7299b..bb6ce70 100644 (file)
 #define SIG_CPU_NMI                            103     /*!< Make non maskable  interrupt (NMI) to a target CPU. */
 #define SIG_CPU_BUSREQ                 104     /*!< Make bus request (BUSREQ) to a target CPU. Normally non-zero request to release bus (mostly to halt) to target.*/
 #define SIG_CPU_HALTREQ                        105     /*!< Make HALT request to a target CPU.Some devices requires halt request separating with BUSREQ. */
-#define SIG_CPU_DEBUG                  106     /*!< Make DEBUG pin request to a target */ 
-#define SIG_CPU_ADDRESS_DIRTY  107     /*!< Notify  ARG address of taget made dirty.Will use for cache controlling. */ 
-#define SIG_CPU_TOTAL_CYCLE_LO 108     /*!< Get LOW DWORD of total_icount of a target. */
-#define SIG_CPU_TOTAL_CYCLE_HI 109     /*!< Get HIGH DWORD of total_icount of a target. */
-#define SIG_CPU_WAIT_FACTOR            110     /*!< Set / Get wait factor of a target.This is useful for variable CPU clocks. This value encodes multiply of 65536. */
+#define SIG_CPU_WAIT                   106
+#define SIG_CPU_DEBUG                  107     /*!< Make DEBUG pin request to a target */
 
-#define SIG_PRINTER_DATA       201 /*! Read/Write DATA of (pseudo) printer port (normally 8bit or 16bit width) . */ 
-#define SIG_PRINTER_STROBE     202 /*! Read/Write STROBE SIGNAL to (pseudo) printer port. */ 
-#define SIG_PRINTER_RESET      203 /*! Read/Write RESET SIGNAL of (pseudo) printer port. */ 
-#define SIG_PRINTER_BUSY       204 /*! Read/Write BUSY SIGNAL of (pseudo) printer port. */ 
-#define SIG_PRINTER_ACK                205 /*! Read/Write ACKNOWLEDGE SIGNAL of (pseudo) printer port. */ 
-#define SIG_PRINTER_SELECT     206 /*! Read/Write SELECT SIGNAL of (pseudo) printer port. */ 
+/*!< Extra signals 190-199. */
+#define SIG_CPU_TOTAL_CYCLE_LO 190     /*!< Get LOW DWORD of total_icount of a target. */
+#define SIG_CPU_TOTAL_CYCLE_HI 191     /*!< Get HIGH DWORD of total_icount of a target. */
+#define SIG_CPU_WAIT_FACTOR            192     /*!< Set / Get wait factor of a target.This is useful for variable CPU clocks. This value encodes multiply of 65536. */
+#define SIG_CPU_ADDRESS_DIRTY  193     /*!< Notify  ARG address of taget made dirty.Will use for cache controlling. */
 
-#define SIG_SCSI_DAT                   301 /*! Read from / Write to a DATA BUS of SCSI bus.Normally 8bit width, but sometimes 16bit width. */ 
+#define SIG_PRINTER_DATA       201 /*! Read/Write DATA of (pseudo) printer port (normally 8bit or 16bit width) . */
+#define SIG_PRINTER_STROBE     202 /*! Read/Write STROBE SIGNAL to (pseudo) printer port. */
+#define SIG_PRINTER_RESET      203 /*! Read/Write RESET SIGNAL of (pseudo) printer port. */
+#define SIG_PRINTER_BUSY       204 /*! Read/Write BUSY SIGNAL of (pseudo) printer port. */
+#define SIG_PRINTER_ACK                205 /*! Read/Write ACKNOWLEDGE SIGNAL of (pseudo) printer port. */
+#define SIG_PRINTER_SELECT     206 /*! Read/Write SELECT SIGNAL of (pseudo) printer port. */
+
+#define SIG_SCSI_DAT                   301 /*! Read from / Write to a DATA BUS of SCSI bus.Normally 8bit width, but sometimes 16bit width. */
 #define SIG_SCSI_BSY                   302 /*! Read/Send a BUSY SIGNAL of SCSI bus.*/
 #define SIG_SCSI_CD                            303 /*! Read/Send a CD SIGNAL of SCSI bus.*/
 #define SIG_SCSI_IO                            304 /*! Read/Send a I/O SIGNAL of SCSI bus.*/
index 17cd2fb..942e069 100644 (file)
@@ -25,20 +25,21 @@ void EVENT::initialize()
                config.cpu_power = 0;
        }
        power = config.cpu_power;
-       
+       cache_drive_vm_in_opecode = config.drive_vm_in_opecode;
+
        // initialize sound buffer
        sound_buffer = NULL;
        sound_tmp = NULL;
-       
+
        dont_skip_frames = 0;
        prev_skip = next_skip = false;
        sound_changed = false;
-       
+
        // temporary
        frame_clocks = (int)((double)d_cpu[0].cpu_clocks / (double)FRAMES_PER_SEC + 0.5);
        vline_start_clock = 0;
        cur_vline = 0;
-       vline_clocks[0] = (int)((double)d_cpu[0].cpu_clocks / (double)FRAMES_PER_SEC / (double)LINES_PER_FRAME + 0.5);
+       vclocks[0] = (int)((double)d_cpu[0].cpu_clocks / (double)FRAMES_PER_SEC / (double)LINES_PER_FRAME + 0.5);
 }
 
 void EVENT::initialize_sound(int rate, int samples)
@@ -151,10 +152,11 @@ void EVENT::reset()
                        cancel_event(NULL, i);
                }
        }
-       
-       event_remain = event_extra = 0;
-       cpu_remain = cpu_accum = cpu_done = 0;
-       
+
+       event_clocks_remain = 0;
+       cpu_clocks_remain = cpu_clocks_accum = cpu_clocks_done = 0;
+       cache_drive_vm_in_opecode = config.drive_vm_in_opecode;
+
        // reset sound
        if(sound_buffer) {
                memset(sound_buffer, 0, sound_samples * sizeof(uint16_t) * 2);
@@ -171,29 +173,36 @@ void EVENT::reset()
 
 void EVENT::drive()
 {
-       if(event_half) goto skip1;
+       // Update cache from config.drive_vm_in_opecode .
+       cache_drive_vm_in_opecode = config.drive_vm_in_opecode;
+       if(event_half) {
+               goto skip1;
+       }
+
        // raise pre frame events to update timing settings
        for(int i = 0; i < frame_event_count; i++) {
                frame_event[i]->event_pre_frame();
        }
-       
+
        // generate clocks per line
        if(frames_per_sec != next_frames_per_sec || lines_per_frame != next_lines_per_frame) {
                frames_per_sec = next_frames_per_sec;
                lines_per_frame = next_lines_per_frame;
-               
+
                frame_clocks = (int)((double)d_cpu[0].cpu_clocks / frames_per_sec + 0.5);
                int remain = frame_clocks;
-               
+
                for(int i = 0; i < lines_per_frame; i++) {
-                       assert(i < MAX_LINES);
-                       vline_clocks[i] = (int)(frame_clocks / lines_per_frame);
-                       remain -= vline_clocks[i];
+                       //assert(i < MAX_LINES);
+                       __UNLIKELY_IF(i >= MAX_LINES) break;
+                       vclocks[i] = (int)(frame_clocks / lines_per_frame);
+                       remain -= vclocks[i];
                }
                for(int i = 0; i < remain; i++) {
                        int index = (int)((double)lines_per_frame * (double)i / (double)remain);
-                       assert(index < MAX_LINES);
-                       vline_clocks[index]++;
+                       //assert(index < MAX_LINES);
+                       __UNLIKELY_IF(index >= MAX_LINES) break;
+                       vclocks[index]++;
                }
                for(int i = 1; i < dcount_cpu; i++) {
                        d_cpu[i].update_clocks = (int)(1024.0 * (double)d_cpu[i].cpu_clocks / (double)d_cpu[0].cpu_clocks + 0.5);
@@ -205,25 +214,23 @@ void EVENT::drive()
                        }
                }
        }
-               
+
        // run virtual machine for 1 frame period
        for(int i = 0; i < frame_event_count; i++) {
                frame_event[i]->event_frame();
        }
-       
        cur_vline = 0;
        vline_start_clock = get_current_clock();
-       
        for(int i = 0; i < vline_event_count; i++) {
-               vline_event[i]->event_vline(cur_vline, vline_clocks[cur_vline]);
+               vline_event[i]->event_vline(cur_vline, vclocks[cur_vline]);
        }
-       this->register_event_by_clock(this, EVENT_VLINE, vline_clocks[cur_vline], false, NULL);
-       
-       if(event_remain < 0) {
-               if(-event_remain > vline_clocks[cur_vline]) {
-                       update_event(vline_clocks[cur_vline]);
+       register_event_by_clock(this, EVENT_VLINE, vclocks[cur_vline], false, NULL);
+
+       if(event_clocks_remain < 0) {
+               if(-event_clocks_remain > vclocks[cur_vline]) {
+                       update_event(vclocks[cur_vline]);
                } else {
-                       update_event(-event_remain);
+                       update_event(-event_clocks_remain);
                }
        }
 skip1:
@@ -234,120 +241,126 @@ skip1:
                _fclocks = frame_clocks / 2;
        }
        event_half = !(event_half);
-//     event_remain += frame_clocks;
-//     cpu_remain += frame_clocks << power;
-       event_remain += _fclocks;
-       cpu_remain += _fclocks << power;
-       
-       while(event_remain > 0) {
-               int event_done = event_remain;
-               __LIKELY_IF(cpu_remain > 0) {
+       event_clocks_remain += _fclocks;
+       cpu_clocks_remain += _fclocks << power;
+
+       while(event_clocks_remain > 0) {
+               int event_clocks_done = event_clocks_remain;
+               __LIKELY_IF(cpu_clocks_remain > 0) {
                        event_extra = 0;
-                       int cpu_done_tmp;
+                       int cpu_clocks_done_tmp;
                        __LIKELY_IF(dcount_cpu == 1) {
                                // run one opecode on primary cpu
-//                             cpu_done_tmp = d_cpu[0].device->run(-1);
-                               cpu_done_tmp = d_cpu[0].device->run(-1);
+                               cpu_clocks_in_opecode = 0;
+                               cpu_clocks_done_tmp  = d_cpu[0].device->run(-1);
+                               cpu_clocks_done_tmp -= cpu_clocks_in_opecode;
+                               #ifdef _DEBUG
+                               assert(cpu_clocks_done_tmp >= 0);
+                               #endif
+                               if(cpu_clocks_done_tmp < 0) cpu_clocks_done_tmp = 0;
                        } else {
                                // sync to sub cpus
-                               if(cpu_done == 0) {
+                               if(cpu_clocks_done == 0) {
                                        // run one opecode on primary cpu
-                                       cpu_done = d_cpu[0].device->run(-1);
-                               }
-                               
-                               // sub cpu runs continuously and no events will be fired while the given clocks,
-                               // so I need to give small enough clocks...
-#if 1
-//                             cpu_done_tmp = (event_extra > 0 || cpu_done < 256) ? cpu_done : 256;
-//                             cpu_done -= cpu_done_tmp;
-                               cpu_done_tmp = cpu_done;
-                               cpu_done = 0;           ;
-                               for(int i = 1; i < dcount_cpu; i++) {
-                                       // run sub cpus
-                                       int clock_result = d_cpu[i].update_clocks * cpu_done_tmp;
-                                       int sub_clock = 0;
-                                       int sub_clock2 = 0;
-                                       if(clock_result > 0) {
-                                               __UNLIKELY_IF(clock_result >= 0x400) { // OVER 1 clocks with HOST, to reduce risk of overflow@accum_clocks.
-                                                       // Upper clocks are not to need to add accum_clocks,
-                                                       // accum_clocks may be effected by lower value of clock_result,
-                                                       // *excepts multiply value (of adding value to accum_clocks) isn't 2^x*.
-                                                       // 20191013 K.O
-                                                       sub_clock = (int)(clock_result >> 10);
-                                                       // Update only execution clocks (executing later)
-                                                       //d_cpu[i].device->run(sub_clock); // Execute over 1 host clocks.
-                                                       clock_result -= (sub_clock << 10);
-                                               }
-                                               d_cpu[i].accum_clocks += clock_result; // At most, 1 host clocks.Guranteed maximum at 1 host clocks.
-                                               sub_clock2 = (int)(d_cpu[i].accum_clocks >> 10);
-                                               sub_clock += sub_clock2;
-                                               __LIKELY_IF(sub_clock > 0) {
-                                                       d_cpu[i].accum_clocks -= sub_clock2 << 10;
-                                                       d_cpu[i].device->run(sub_clock);
+                                       cpu_clocks_in_opecode = 0;
+                                       cpu_clocks_done  = d_cpu[0].device->run(-1);
+                                       cpu_clocks_done -= cpu_clocks_in_opecode;
+                                       #ifdef _DEBUG
+                                       assert(cpu_clocks_done >= 0);
+                                       #endif
+                                       if(cpu_clocks_done < 0) cpu_clocks_done = 0;
+
+                                       // run sub cpus because the event has been aleady proceeded
+                                       if(cpu_clocks_in_opecode > 0) {
+                                               for(int i = 1; i < dcount_cpu; i++) {
+                                                       // ToDo: Against Integer overflow. 20230305 K.O
+                                                       int clock_result = d_cpu[i].update_clocks * cpu_clocks_in_opecode;
+                                                       d_cpu[i].accum_clocks += clock_result;
+                                                       int sub_clock = d_cpu[i].accum_clocks >> 10;
+                                                       __UNLIKELY_IF(sub_clock > 0) {
+                                                               d_cpu[i].accum_clocks -= sub_clock << 10;
+                                                               d_cpu[i].device->run(sub_clock);
+                                                       }
                                                }
                                        }
                                }
-#else
-                               cpu_done_tmp = (event_extra > 0 || cpu_done < 4) ? cpu_done : 4;
-                               cpu_done -= cpu_done_tmp;
-                               for(int i = 1; i < dcount_cpu; i++) {
-                                       // run sub cpus
-                                       int clock_result = d_cpu[i].update_clocks * cpu_done_tmp;
-                                       int sub_clock;
-                                       d_cpu[i].accum_clocks += clock_result; // At most, 16 host clocks.Guranteed maximum at 16 host clocks.
-                                       sub_clock = (int)(d_cpu[i].accum_clocks >> 10);
-                                       __LIKELY_IF(sub_clock > 0) {
-                                               d_cpu[i].accum_clocks -= sub_clock << 10;
-                                               d_cpu[i].device->run(sub_clock);
+                               __LIKELY_IF(cpu_clocks_done > 0) {
+                                       // sub cpu runs continuously and no events will be fired while the given clocks,
+                                       // so I need to give small enough clocks...
+                                       cpu_clocks_done_tmp = (cpu_clocks_done < 4) ? cpu_clocks_done : 4;
+                                       cpu_clocks_done -= cpu_clocks_done_tmp;
+
+                                       for(int i = 1; i < dcount_cpu; i++) {
+                                               // ToDo: Against integer overflow. 20230305 K.O
+                                               // run sub cpus
+                                               d_cpu[i].accum_clocks += d_cpu[i].update_clocks * cpu_clocks_done_tmp;
+                                               int sub_clock = d_cpu[i].accum_clocks >> 10;
+                                               __UNLIKELY_IF(sub_clock) {
+                                                       d_cpu[i].accum_clocks -= sub_clock << 10;
+                                                       d_cpu[i].device->run(sub_clock);
+                                               }
                                        }
+                               } else {
+                                       cpu_clocks_done_tmp = 0;
                                }
-#endif
                        }
-                       cpu_remain -= cpu_done_tmp;
-                       cpu_accum += cpu_done_tmp;
-                       event_done = cpu_accum >> power;
-                       cpu_accum -= event_done << power;
-                       event_done -= event_extra;
+                       if(cpu_clocks_done_tmp > 0) {
+                               // ToDo: Against integer overflow. 20230305 K.O
+                               cpu_clocks_remain -= cpu_clocks_done_tmp;
+                               cpu_clocks_accum += cpu_clocks_done_tmp;
+                               event_clocks_done = cpu_clocks_accum >> power;
+                               cpu_clocks_accum -= event_clocks_done << power;
+                       } else {
+                               event_clocks_done = 0;
+                       }
                }
-               __LIKELY_IF(event_done > 0) {
-                       if(event_remain > 0) {
-                               __UNLIKELY_IF(event_done > event_remain) {
-                                       update_event(event_remain);
+               // ToDo: Against integer overflow. 20230305 K.O
+               if(event_clocks_done > 0) {
+                       if(event_clocks_remain > 0) {
+                               if(event_clocks_done > event_clocks_remain) {
+                                       update_event(event_clocks_remain);
                                } else {
-                                       update_event(event_done);
+                                       update_event(event_clocks_done);
                                }
                        }
-                       event_remain -= event_done;
+                       event_clocks_remain -= event_clocks_done;
                }
        }
 }
 
-void EVENT::update_extra_event(int clock)
+void EVENT::update_event_in_opecode(int clock)
 {
        // this is called from primary cpu while running one opecode
-       int event_done = clock >> power;
-       
-       if(event_done > 0) {
-               if(event_remain > 0) {
-                       if(event_done > event_remain) {
-                               update_event(event_remain);
-                       } else {
-                               update_event(event_done);
+       // Note: Cache  config.drive_vm_in_opecode expecting to be faster.
+       if(cache_drive_vm_in_opecode) {
+               // ToDo: Against integer overflow. 20230305 K.O
+               cpu_clocks_in_opecode += clock;
+               cpu_clocks_remain -= clock;
+               cpu_clocks_accum += clock;
+               int event_clocks_done = cpu_clocks_accum >> power;
+               cpu_clocks_accum -= event_clocks_done << power;
+
+               if(event_clocks_done > 0) {
+                       if(event_clocks_remain > 0) {
+                               if(event_clocks_done > event_clocks_remain) {
+                                       update_event(event_clocks_remain);
+                               } else {
+                                       update_event(event_clocks_done);
+                               }
                        }
+                       event_clocks_remain -= event_clocks_done;
                }
-               event_remain -= event_done;
-               event_extra += event_done;
        }
 }
 
 void EVENT::update_event(int clock)
 {
        uint64_t event_clocks_tmp = event_clocks + clock;
-       
+
        while(first_fire_event != NULL && first_fire_event->expired_clock <= event_clocks_tmp) {
                event_t *event_handle = first_fire_event;
                uint64_t expired_clock = event_handle->expired_clock;
-               
+
                first_fire_event = event_handle->next;
                __UNLIKELY_IF(first_fire_event != NULL) {
                        first_fire_event->prev = NULL;
@@ -427,7 +440,7 @@ void EVENT::register_event(DEVICE* device, int event_id, double usec, bool loop,
                this->out_debug_log(_T("EVENT: non-loop event is registered before initialize is done\n"));
        }
 #endif
-       
+
        // register event
        __UNLIKELY_IF(first_free_event == NULL) {
 #ifdef _DEBUG_LOG
@@ -440,7 +453,7 @@ void EVENT::register_event(DEVICE* device, int event_id, double usec, bool loop,
        }
        event_t *event_handle = first_free_event;
        first_free_event = first_free_event->next;
-       
+
        __LIKELY_IF(register_id != NULL) {
                *register_id = event_handle->index;
        }
@@ -459,7 +472,7 @@ void EVENT::register_event(DEVICE* device, int event_id, double usec, bool loop,
                event_handle->accum_clocks = 0;
        }
        event_handle->expired_clock = event_clocks + clock;
-       
+
        insert_event(event_handle);
 }
 
@@ -470,7 +483,7 @@ void EVENT::register_event_by_clock(DEVICE* device, int event_id, uint64_t clock
                this->out_debug_log(_T("EVENT: device (name=%s, id=%d) registeres non-loop event before initialize is done\n"), device->this_device_name, device->this_device_id);
        }
 #endif
-       
+
        // register event
        __UNLIKELY_IF(first_free_event == NULL) {
 #ifdef _DEBUG_LOG
@@ -483,7 +496,7 @@ void EVENT::register_event_by_clock(DEVICE* device, int event_id, uint64_t clock
        }
        event_t *event_handle = first_free_event;
        first_free_event = first_free_event->next;
-       
+
        __LIKELY_IF(register_id != NULL) {
                *register_id = event_handle->index;
        }
@@ -493,7 +506,7 @@ void EVENT::register_event_by_clock(DEVICE* device, int event_id, uint64_t clock
        event_handle->expired_clock = event_clocks + clock;
        event_handle->loop_clock = loop ? (clock << 10) : 0;
        event_handle->accum_clocks = 0;
-       
+
        insert_event(event_handle);
 }
 
@@ -540,7 +553,7 @@ void EVENT::cancel_event(DEVICE* device, int register_id)
                        this->out_debug_log(_T("EVENT: device (name=%s, id=%d) tries to cancel event %d that is not its own (owned by (name=%s id=%d))!!!\n"), device->this_device_name, device->this_device_id,
                                                                register_id,
                                                                event_handle->device->this_device_name,
-                                                               event_handle->device->this_device_id);                  
+                                                               event_handle->device->this_device_id);
                        return;
                }
                __LIKELY_IF(event_handle->active) {
@@ -650,10 +663,10 @@ void EVENT::event_callback(int event_id, int err)
                        buffer_ptr = 0;
                }
                int remain = sound_tmp_samples - buffer_ptr;
-               
+
                if(remain > 0) {
                        int samples = mix_counter;
-                       
+
                        if(config.sound_strict_rendering || (need_mix > 0)) {
                                if(samples < 1) {
                                        samples = 1;
@@ -679,14 +692,14 @@ void EVENT::event_callback(int event_id, int err)
                if(cur_vline + 1 < lines_per_frame) {
                        cur_vline++;
                        vline_start_clock = get_current_clock();
-                       
+
                        for(int i = 0; i < vline_event_count; i++) {
-                               vline_event[i]->event_vline(cur_vline, vline_clocks[cur_vline]);
+                               vline_event[i]->event_vline(cur_vline, vclocks[cur_vline]);
                        }
-                       
+
                        // do not register if next vline is the first vline of next frame
                        if(cur_vline + 1 < lines_per_frame) {
-                               this->register_event_by_clock(this, EVENT_VLINE, vline_clocks[cur_vline], false, NULL);
+                               this->register_event_by_clock(this, EVENT_VLINE, vclocks[cur_vline], false, NULL);
                        }
                }
        }
@@ -729,7 +742,7 @@ uint16_t* EVENT::create_sound(int* extra_frames)
                return sound_buffer;
        }
        int frames = 0;
-       
+
        // drive extra frames to fill the sound buffer
        while(sound_samples > buffer_ptr) {
                drive();
@@ -738,7 +751,7 @@ uint16_t* EVENT::create_sound(int* extra_frames)
        int _total_div = (sound_samples * 2) >> 3;
        int _total_mod = (sound_samples * 2) - (((sound_samples * 2) >> 3) << 3);
        __DECL_ALIGNED(32) int32_t tmpbuf[16];
-       
+
 #ifdef LOW_PASS_FILTER
        // low-pass filter
        for(int i = 0; i < sound_samples - 1; i++) {
@@ -770,7 +783,7 @@ uint16_t* EVENT::create_sound(int* extra_frames)
                }
                ii += 8;
        }
-       
+
        int16_t* np = (int16_t*)(&sound_buffer[ii]);
        for(int i = 0; i < _total_mod; i++) {
                int32_t dat = sound_tmp[ii + i];
@@ -802,7 +815,7 @@ bool EVENT::is_sound_in_source_exists(int bank)
        bool f = true;
        if(bank < 0) return false;
        if(bank >= MAX_SOUND_IN_BUFFERS) return false;
-       
+
        // ToDo: Lock Mutex
        if(sound_in_tmp_buffer[bank] == NULL) f = false;
        // ToDo: UnLock Mutex
@@ -954,12 +967,12 @@ int EVENT::increment_sound_in_passed_data(int bank, double passed_usec)
        if(sound_in_rate[bank] <= 0) return 0;
        if(sound_in_samples[bank] <= 0) return 0;
        if(passed_usec <= 0.0) return 0;
-       
+
        double freq = 1.0e6 / sound_in_rate[bank];
        int inc_ptr = (int)(nearbyint(passed_usec / freq));
        int readptr = sound_in_readptr[bank];
        int _ni = inc_ptr;
-       
+
        if(_ni >= sound_in_samples[bank]) {
                _ni = _ni % sound_in_samples[bank];
        }
@@ -976,7 +989,7 @@ int EVENT::increment_sound_in_passed_data(int bank, double passed_usec)
        }
        return inc_ptr;
 }
-       
+
 int EVENT::get_sound_in_latest_data(int bank, int32_t* dst, int expect_channels)
 {
        int gave_samples = 0;
@@ -1002,7 +1015,7 @@ int EVENT::get_sound_in_latest_data(int bank, int32_t* dst, int expect_channels)
        int16_t* p = sound_in_tmp_buffer[bank];
        if(p == NULL) return 0;
        p =&(p[readptr * sound_in_channels[bank]]);
-       
+
        for(int i = 0; i < sound_in_channels[bank]; i++) {
                tmpbuf[i] = p[i];
        }
@@ -1013,7 +1026,7 @@ int EVENT::get_sound_in_latest_data(int bank, int32_t* dst, int expect_channels)
        }
        sound_in_readptr[bank] = readptr;
        sound_in_write_size[bank] = 0;
-       return rechannel_sound_in_data(dst, tmpbuf, expect_channels, sound_in_channels[bank], 1); 
+       return rechannel_sound_in_data(dst, tmpbuf, expect_channels, sound_in_channels[bank], 1);
 }
 
 int EVENT::get_sound_in_data(int bank, int32_t* dst, int expect_samples, int expect_rate, int expect_channels)
@@ -1027,7 +1040,7 @@ int EVENT::get_sound_in_data(int bank, int32_t* dst, int expect_samples, int exp
        int readptr = sound_in_readptr[bank];
        if(readptr < 0) readptr = 0;
        if(readptr >= sound_in_samples[bank]) readptr = 0;
-       
+
        int gave_samples = 0;
        // ToDo: Lock Mutex
        int in_count;
@@ -1039,7 +1052,7 @@ int EVENT::get_sound_in_data(int bank, int32_t* dst, int expect_samples, int exp
        int16_t tmpbuf_in[(in_count + 1) * sound_in_channels[bank]];
        int32_t tmpbuf[(in_count + 1) * expect_channels];
        memset(tmpbuf, 0x00, sizeof(int32_t) * (in_count + 1) * expect_channels);
-       
+
        int mp = 0;
        for(int i = 0; i < in_count; i++) {
                int tmpr = readptr * sound_in_channels[bank];
@@ -1053,15 +1066,15 @@ int EVENT::get_sound_in_data(int bank, int32_t* dst, int expect_samples, int exp
        sound_in_readptr[bank] = readptr;
        sound_in_write_size[bank] -= in_count;
        if(sound_in_write_size[bank] <= 0) sound_in_write_size[bank] = 0;
-       
+
        gave_samples = rechannel_sound_in_data(tmpbuf, tmpbuf_in, expect_channels, sound_in_channels[bank], in_count);
-       
+
        // ToDo: UnLock Mutex
        // Got to TMP Buffer
        if(expect_rate == sound_in_rate[bank]) {
                int32_t* p = tmpbuf;
                int32_t* q = dst;
-               
+
                for(int i = 0; i < (gave_samples * expect_channels); i++) {
                        q[i] = p[i];
                }
@@ -1144,7 +1157,7 @@ void EVENT::request_skip_frames()
 bool EVENT::is_frame_skippable()
 {
        bool value = next_skip;
-       
+
        if(sound_changed || (prev_skip && !next_skip)) {
                dont_skip_frames = (int)frames_per_sec;
        }
@@ -1155,15 +1168,16 @@ bool EVENT::is_frame_skippable()
        prev_skip = next_skip;
        next_skip = false;
        sound_changed = false;
-       
+
        return value;
 }
 
 void EVENT::update_config()
 {
+       cache_drive_vm_in_opecode = config.drive_vm_in_opecode;
        if(power != config.cpu_power) {
                power = config.cpu_power;
-               cpu_accum = 0;
+               cpu_clocks_accum = 0;
        }
 }
 
@@ -1187,12 +1201,12 @@ bool EVENT::process_state(FILEIO* state_fio, bool loading)
                state_fio->StateValue(d_cpu[i].accum_clocks);
        }
        state_fio->StateValue(frame_clocks);
-       state_fio->StateArray(vline_clocks, sizeof(vline_clocks), 1);
-       state_fio->StateValue(event_remain);
-       state_fio->StateValue(event_extra);
-       state_fio->StateValue(cpu_remain);
-       state_fio->StateValue(cpu_accum);
-       state_fio->StateValue(cpu_done);
+       state_fio->StateArray(vclocks, sizeof(vclocks), 1);
+       state_fio->StateValue(event_clocks_remain);
+       state_fio->StateValue(cpu_clocks_remain);
+       state_fio->StateValue(cpu_clocks_accum);
+       state_fio->StateValue(cpu_clocks_done);
+       state_fio->StateValue(cpu_clocks_in_opecode);
        state_fio->StateValue(event_clocks);
        for(int i = 0; i < MAX_EVENT; i++) {
                if(loading) {
@@ -1227,9 +1241,10 @@ bool EVENT::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateArray(dev_need_mix, sizeof(dev_need_mix), 1);
        state_fio->StateValue(need_mix);
        state_fio->StateValue(event_half);
-       
+
        // post process
        if(loading) {
+               cache_drive_vm_in_opecode = config.drive_vm_in_opecode;
                if(sound_buffer) {
                        memset(sound_buffer, 0, sound_samples * sizeof(uint16_t) * 2);
                }
index 99f6a65..60a0da2 100644 (file)
@@ -25,7 +25,7 @@
        #endif
 #endif
 
-/*! 
+/*!
   @class EVENT
   @brief EVENT manager, includes CPUs execution.
   @note Executing event has run per half of a frame by default at CSP/Qt.
@@ -40,8 +40,8 @@ private:
        */
        typedef struct {
                DEVICE* device;                 //!< Target Device ID
-               uint32_t cpu_clocks;    //!< Target CLOCK by 1Hz. 
-               uint32_t update_clocks; //!< Target clock for updating scheduler. 
+               uint32_t cpu_clocks;    //!< Target CLOCK by 1Hz.
+               uint32_t update_clocks; //!< Target clock for updating scheduler.
                uint32_t accum_clocks;  //!< Target clock for accumulation.
        } cpu_t;
        cpu_t d_cpu[MAX_CPU];           //!< TARGET CPU entries to run.
@@ -49,12 +49,12 @@ private:
        uint32_t cpu_update_clocks[MAX_CPU][6];
        int dcount_cpu; //! Numbers of Target CPUs.
 
-       bool event_half;        //! Display second half of frame. 
+       bool event_half;        //! Display second half of frame.
        int frame_clocks;
-       int vline_clocks[MAX_LINES];
+       int vclocks[MAX_LINES];
        int power;
-       int event_remain, event_extra;
-       int cpu_remain, cpu_accum, cpu_done;
+       int event_clocks_remain;
+       int cpu_clocks_remain, cpu_clocks_accum, cpu_clocks_done, cpu_clocks_in_opecode;
        uint64_t event_clocks;
 
        /*!
@@ -78,19 +78,19 @@ private:
        DEVICE* frame_event[MAX_EVENT];
        DEVICE* vline_event[MAX_EVENT];
        int frame_event_count, vline_event_count;
-       
+
        double frames_per_sec, next_frames_per_sec;
        int lines_per_frame, next_lines_per_frame;
        uint32_t vline_start_clock;
        int cur_vline;
-       
-       void update_event(int clock);
-       void insert_event(event_t *event_handle);
-       
+
+       void __FASTCALL update_event(int clock);
+       void __FASTCALL insert_event(event_t *event_handle);
+
        // sound manager
        DEVICE* d_sound[MAX_SOUND];
        int dcount_sound;
-       
+
        uint16_t* sound_buffer;
        int32_t* sound_tmp;
        int buffer_ptr;
@@ -106,19 +106,20 @@ private:
        int sound_in_write_size[MAX_SOUND_IN_BUFFERS];
        int sound_in_read_size[MAX_SOUND_IN_BUFFERS];
        int sound_in_read_mod[MAX_SOUND_IN_BUFFERS];
-       
+
        int dont_skip_frames;
        bool prev_skip, next_skip;
        bool sound_changed;
-       
+
        int mix_counter;
        int mix_limit;
        bool dev_need_mix[MAX_DEVICE];
        int need_mix;
-       
+
        void __FASTCALL mix_sound(int samples);
        void* __FASTCALL get_event(int index);
-
+       // Note: Cache  config.drive_vm_in_opecode expecting to be faster.20230305 K.O
+       bool cache_drive_vm_in_opecode;
 #ifdef _DEBUG_LOG
        bool initialize_done;
 #endif
@@ -127,7 +128,7 @@ public:
        {
                dcount_cpu = dcount_sound = 0;
                frame_event_count = vline_event_count = 0;
-               
+
                // initialize event
                memset(event, 0, sizeof(event));
                for(int i = 0; i < MAX_EVENT; i++) {
@@ -137,9 +138,9 @@ public:
                }
                first_free_event = &event[0];
                first_fire_event = NULL;
-               
+
                event_clocks = 0;
-               
+
                // force update timing in the first frame
                frames_per_sec = 0.0;
                lines_per_frame = 0;
@@ -148,7 +149,7 @@ public:
                // reset before other device may call set_realtime_render()
                memset(dev_need_mix, 0, sizeof(dev_need_mix));
                need_mix = 0;
-               
+
                for(int i = 0; i < MAX_SOUND_IN_BUFFERS; i++) {
                        sound_in_tmp_buffer[i] = NULL;
                        sound_in_rate[i] = 0;
@@ -166,27 +167,27 @@ public:
                set_device_name(_T("Event Manager"));
        }
        ~EVENT() {}
-       
+
        // common functions
-       void initialize();
-       void release();
-       void reset();
-       void __FASTCALL event_callback(int event_id, int err);
-       void update_config();
-       bool process_state(FILEIO* state_fio, bool loading);
-       
+       void initialize() override;
+       void release() override;
+       void reset() override;
+       void __FASTCALL event_callback(int event_id, int err) override;
+       void update_config() override;
+       bool process_state(FILEIO* state_fio, bool loading) override;
+
        //! common event functions
-       /*! 
+       /*!
          @brief Get DEVICE ID of event manager.
        */
-       int get_event_manager_id()
+       int get_event_manager_id() override
        {
                return this_device_id;
        }
-       /*! 
+       /*!
          @brief Get clock Hz of first CPU.
        */
-       uint32_t get_event_clocks()
+       uint32_t get_event_clocks() override
        {
                return d_cpu[0].cpu_clocks;
        }
@@ -195,7 +196,7 @@ public:
          @param device Device pointer to check.
          @return true if primary CPU (CPU #0).
        */
-       bool is_primary_cpu(DEVICE* device)
+       bool is_primary_cpu(DEVICE* device) override
        {
                return (d_cpu[0].device == device);
        }
@@ -205,7 +206,7 @@ public:
          @return clock Hz of target.
          @note return default clock value (= CPU #0) if device is not as CPU.
        */
-       uint32_t __FASTCALL get_cpu_clocks(DEVICE* device)
+       uint32_t __FASTCALL get_cpu_clocks(DEVICE* device) override
        {
                for(int index = 0; index < dcount_cpu; index++) {
                        if(d_cpu[index].device == device) {
@@ -219,7 +220,7 @@ public:
         @param new_frames_per_sec Framerate after next frame rate by 1Sec.
         @note This change will effect after frame rate, not at this frame rate.
        */
-       void set_frames_per_sec(double new_frames_per_sec)
+       void set_frames_per_sec(double new_frames_per_sec) override
        {
                next_frames_per_sec = new_frames_per_sec;
        }
@@ -229,7 +230,7 @@ public:
         @note This change will effect after frame period, not at this frame period.
         @note Lines limits from 1 to MAX_LINES .
        */
-       void set_lines_per_frame(int new_lines_per_frame)
+       void set_lines_per_frame(int new_lines_per_frame) override
        {
                if(new_lines_per_frame < MAX_LINES) {
                        next_lines_per_frame = new_lines_per_frame;
@@ -239,32 +240,32 @@ public:
          @brief Get lines per frame of next frame period.
          @return Lines per frame of next frame period, not current period.
        */
-       int get_lines_per_frame()
+       int get_lines_per_frame() override
        {
                return next_lines_per_frame;
        }
        /*!
          @brief Update extra events if remains host time.
          @param clock clocks. Still dummy.
-       */ 
-       void __FASTCALL update_extra_event(int clock);
-       void register_event(DEVICE* device, int event_id, double usec, bool loop, int* register_id);
-       void register_event_by_clock(DEVICE* device, int event_id, uint64_t clock, bool loop, int* register_id);
-       void cancel_event(DEVICE* device, int register_id);
-       void register_frame_event(DEVICE* device);
-       void register_vline_event(DEVICE* device);
-       uint32_t __FASTCALL get_event_remaining_clock(int register_id);
-       double __FASTCALL get_event_remaining_usec(int register_id);
-       uint32_t get_current_clock();
-       uint32_t __FASTCALL get_passed_clock(uint32_t prev);
-       double __FASTCALL get_passed_usec(uint32_t prev);
-       uint32_t get_passed_clock_since_vline();
-       double get_passed_usec_since_vline();
+       */
+       void __FASTCALL update_event_in_opecode(int clock) override;
+       void register_event(DEVICE* device, int event_id, double usec, bool loop, int* register_id) override;
+       void register_event_by_clock(DEVICE* device, int event_id, uint64_t clock, bool loop, int* register_id) override;
+       void cancel_event(DEVICE* device, int register_id) override;
+       void register_frame_event(DEVICE* device) override;
+       void register_vline_event(DEVICE* device) override;
+       uint32_t __FASTCALL get_event_remaining_clock(int register_id) override;
+       double __FASTCALL get_event_remaining_usec(int register_id) override;
+       uint32_t get_current_clock() override;
+       uint32_t __FASTCALL get_passed_clock(uint32_t prev) override;
+       double __FASTCALL get_passed_usec(uint32_t prev) override;
+       uint32_t get_passed_clock_since_vline() override;
+       double get_passed_usec_since_vline() override;
        /*!
         @brief Get current proccessing position of vertical line.
         @return Cureent position.
        */
-       int get_cur_vline()
+       int get_cur_vline() override
        {
                return cur_vline;
        }
@@ -272,16 +273,16 @@ public:
         @brief Get relative clock position value at current line.
         @return Cureent clock position.
        */
-       int get_cur_vline_clocks()
+       int get_cur_vline_clocks() override
        {
                return vline_clocks[cur_vline];
        }
-       uint32_t __FASTCALL get_cpu_pc(int index);
-       void request_skip_frames();
-       void touch_sound();
-       void set_realtime_render(DEVICE* device, bool flag);
-       uint64_t get_current_clock_uint64();
-       double get_current_usec();
+       uint32_t __FASTCALL get_cpu_pc(int index) override;
+       void request_skip_frames() override;
+       void touch_sound() override;
+       void set_realtime_render(DEVICE* device, bool flag) override;
+       uint64_t get_current_clock_uint64() override;
+       double get_current_usec() override;
        uint32_t __FASTCALL get_cpu_clock(int index);
        // unique functions
        /*!
@@ -294,7 +295,7 @@ public:
                return next_frames_per_sec;
        }
        void drive();
-       
+
        void initialize_sound(int rate, int samples);
        uint16_t* __FASTCALL create_sound(int* extra_frames);
        int get_sound_buffer_ptr();
@@ -302,7 +303,7 @@ public:
        void clear_sound_in_source(int bank);
        int add_sound_in_source(int rate, int samples, int channels);
        int release_sound_in_source(int bank);
-       
+
        bool is_sound_in_source_exists(int bank);
        int __FASTCALL increment_sound_in_passed_data(int bank, double passed_usec);
        int get_sound_in_buffers_count();
@@ -420,4 +421,3 @@ public:
 
 
 #endif
-
index 0933d23..436902e 100644 (file)
@@ -1,7 +1,7 @@
 cmake_minimum_required (VERSION 3.0)
 
 message("* vm/fmgen")
-SET(THIS_LIB_VERSION 5.5.6)
+SET(THIS_LIB_VERSION 5.6.0)
 add_definitions(-D__LIBFMGEN_VERSION=\"libCSPfmgen.${THIS_LIB_VERSION}\")
 
 SET(s_vm_fmgen_srcs
index b6beb74..c5b85e6 100644 (file)
@@ -64,7 +64,7 @@ void TOWNS_MEMORY::config_page_d0_e0()
        if(!(dma_is_vram)) {
                set_memory_rw          (0x000d0000, 0x000effff, ram_paged);
        } else {
-               if(select_d0_dict) { 
+               if(select_d0_dict) {
                        set_memory_mapped_io_rw(0x000d0000, 0x000d9fff, d_dictionary);
                        set_memory_r           (0x000da000, 0x000effff, rd_dummy);
                        set_memory_w           (0x000da000, 0x000effff, wr_dummy);
@@ -79,7 +79,7 @@ void TOWNS_MEMORY::config_page_d0_e0()
 void TOWNS_MEMORY::config_page_f8_rom()
 {
        set_memory_mapped_io_rw (0x000f8000, 0x000fffff, this);
-//             
+//
 //     if(select_d0_rom) {
 //             set_memory_mapped_io_r (0x000f8000, 0x000fffff, d_sysrom);
 //             set_memory_w           (0x000f8000, 0x000fffff, wr_dummy);
@@ -87,20 +87,20 @@ void TOWNS_MEMORY::config_page_f8_rom()
 //             set_memory_rw          (0x000f8000, 0x000fffff, &(ram_pagef[0x8000]));
 //     }
 }
-       
+
 void TOWNS_MEMORY::config_page00()
 {
        config_page_c0();
        config_page_d0_e0();
        config_page_f8_rom();
 }
-       
+
 void TOWNS_MEMORY::initialize()
 {
 //     if(initialized) return;
        MEMORY::initialize();
 //     DEVICE::initialize();
-       
+
        extra_nmi_mask = true;
        extra_nmi_val = false;
        poff_status = false;
@@ -126,7 +126,7 @@ void TOWNS_MEMORY::initialize()
 
        bank_mask = BANK_MASK;
        addr_mask = ADDR_MASK;
-       
+
        initialized = true;
        extram_size = extram_size & 0x3ff00000;
        set_extra_ram_size(extram_size >> 20); // Check extra ram size.
@@ -137,32 +137,32 @@ void TOWNS_MEMORY::initialize()
                        set_memory_rw(0x00100000, (extram_size + 0x00100000) - 1, extra_ram);
                        memset(extra_ram, 0x00, extram_size);
                }
-       }               
+       }
        memset(ram_page0, 0x00, sizeof(ram_page0));
        memset(ram_pagec, 0x00, sizeof(ram_pagec));
        memset(ram_paged, 0x00, sizeof(ram_paged));
        memset(ram_pagef, 0x00, sizeof(ram_pagef));
-       
+
        select_d0_dict = false;
        select_d0_rom = true;
-       
+
        dma_is_vram = true;
        // Lower 100000h
        set_memory_rw          (0x00000000, 0x000bffff, ram_page0);
        set_memory_rw          (0x000f0000, 0x000f7fff, ram_pagef);
        config_page00();
-       
+
        set_memory_mapped_io_rw(0x80000000, 0x8007ffff, d_vram);
        set_memory_mapped_io_rw(0x80100000, 0x8017ffff, d_vram);
        set_memory_mapped_io_rw(0x81000000, 0x8101ffff, d_sprite);
-       
+
 //     set_memory_mapped_io_rw(0xc0000000, 0xc0ffffff, d_iccard[0]);
 //     set_memory_mapped_io_rw(0xc1000000, 0xc1ffffff, d_iccard[1]);
        set_wait_rw(0x00000000, 0xffffffff,  vram_wait_val);
 
        set_memory_mapped_io_rw(0xc0000000, 0xc0ffffff, d_iccard[0]);
        set_memory_mapped_io_rw(0xc1000000, 0xc1ffffff, d_iccard[1]);
-       
+
        set_memory_mapped_io_r (0xc2000000, 0xc207ffff, d_msdos);
        set_memory_mapped_io_r (0xc2080000, 0xc20fffff, d_dictionary);
        set_memory_mapped_io_r (0xc2100000, 0xc213ffff, d_font);
@@ -172,24 +172,24 @@ void TOWNS_MEMORY::initialize()
        }
        set_memory_mapped_io_rw(0xc2200000, 0xc2200fff, d_pcm);
        set_memory_mapped_io_r (0xfffc0000, 0xffffffff, d_sysrom);
-       
+
        set_wait_values();
        // Another devices are blank
-       
+
        // load rom image
        // ToDo: More smart.
        vram_size = 0x80000; // OK?
 }
 
-       
+
 void TOWNS_MEMORY::set_wait_values()
 {
-       uint32_t waitfactor = 1 << 16;
+       uint32_t waitfactor = 0;
        if(cpu_clock_val < get_cpu_clocks(d_cpu)) {
                waitfactor = (uint32_t)(((double)get_cpu_clocks(d_cpu) / (double)cpu_clock_val) * 65536.0);
        }
        d_cpu->write_signal(SIG_CPU_WAIT_FACTOR, waitfactor, 0xffffffff);
-       
+
        set_wait_rw(0x00000000, 0x000bffff, mem_wait_val);
        set_wait_rw(0x000d0000, 0x000fffff, mem_wait_val);
        if(dma_is_vram) {
@@ -198,7 +198,7 @@ void TOWNS_MEMORY::set_wait_values()
                set_wait_rw(0x000c0000, 0x000cffff, mem_wait_val);
        }
        set_wait_rw(0x00100000, 0x00100000 + (extram_size & 0x3ff00000) - 1, mem_wait_val);
-   
+
        // ToDo: Extend I/O Slots
        set_wait_rw(0x80000000, 0x800fffff, vram_wait_val);
        set_wait_rw(0x80100000, 0x801fffff, vram_wait_val);
@@ -221,7 +221,7 @@ void TOWNS_MEMORY::release()
        if(rd_dummy != NULL) free(rd_dummy);
        if(wr_table != NULL) free(wr_table);
        if(wr_dummy != NULL) free(wr_dummy);
-       
+
        if(extra_ram != NULL) {
                free(extra_ram);
                extra_ram = NULL;
@@ -242,7 +242,7 @@ void TOWNS_MEMORY::reset()
        config_page00();
 
        set_wait_values();
-#if 1  
+#if 1
        __LIKELY_IF(d_cpu != NULL) {
                d_cpu->set_address_mask(0xffffffff);
        }
@@ -281,7 +281,7 @@ void TOWNS_MEMORY::update_machine_features()
        }
        // 0025h: NMICNT
        if(machine_id >= 0x0500) { // After CX
-               reg_misc4 = 0x7f; 
+               reg_misc4 = 0x7f;
        } else {
                reg_misc4 = 0xff;
        }
@@ -422,7 +422,7 @@ uint32_t TOWNS_MEMORY::read_io8(uint32_t addr)
                        }
                }
                break;
-          
+
        case 0x05ec:
                if(machine_id >= 0x0200) { // Towns2H/2F : Is this hidden register after Towns 1F/2F/1H/2H? -> Yes
                        val = 0x00;
@@ -549,7 +549,7 @@ void TOWNS_MEMORY::write_io8(uint32_t addr, uint32_t data)
                } else {
                        software_reset = false;
                }
-               
+
                if((data & 0x40) != 0) {
                        poff_status = true;
                        __LIKELY_IF(d_cpu != NULL) {
@@ -564,7 +564,7 @@ void TOWNS_MEMORY::write_io8(uint32_t addr, uint32_t data)
                                d_cpu->set_shutdown_flag(0);
                        }
                }
-               
+
                if(software_reset) {
                        __LIKELY_IF(d_cpu != NULL) {
                                d_cpu->reset();
@@ -577,7 +577,7 @@ void TOWNS_MEMORY::write_io8(uint32_t addr, uint32_t data)
                                d_dmac->write_signal(SIG_TOWNS_DMAC_WRAP_REG, wrap_val, 0xff);
                        }
                }
-               // Towns SEEMS to not set addreess mask (a.k.a A20 mask). 20200131 K.O  
+               // Towns SEEMS to not set addreess mask (a.k.a A20 mask). 20200131 K.O
                break;
        case 0x0022:
                if((data & 0x40) != 0) {
@@ -897,13 +897,13 @@ uint32_t TOWNS_MEMORY::read_data32w(uint32_t addr, int* wait)
                *wait = wr_table[bank].wait;
        }
        return val;
-       
+
 }
 
 uint32_t TOWNS_MEMORY::read_dma_data8(uint32_t addr)
 {
        int bank = (addr & addr_mask) >> addr_shift;
-       
+
        __UNLIKELY_IF(rd_table[bank].device != NULL) {
                return rd_table[bank].device->read_memory_mapped_io8(addr);
        } else {
@@ -914,7 +914,7 @@ uint32_t TOWNS_MEMORY::read_dma_data8(uint32_t addr)
 uint32_t TOWNS_MEMORY::read_dma_data16(uint32_t addr)
 {
        int bank = (addr & addr_mask) >> addr_shift;
-       
+
        __UNLIKELY_IF(rd_table[bank].device != NULL) {
                return rd_table[bank].device->read_memory_mapped_io16(addr);
        } else {
@@ -936,14 +936,14 @@ uint32_t TOWNS_MEMORY::read_dma_data16(uint32_t addr)
 uint32_t TOWNS_MEMORY::read_dma_data32(uint32_t addr)
 {
        int bank = (addr & addr_mask) >> addr_shift;
-       
+
        __UNLIKELY_IF(rd_table[bank].device != NULL) {
                return rd_table[bank].device->read_memory_mapped_io32(addr);
        } else {
                uint32_t naddr = addr & bank_mask;
                pair32_t n;
                n.d = 0;
-               
+
                __UNLIKELY_IF((naddr + 3) > bank_mask) {
                        n.b.l  = rd_table[bank].memory[naddr];
                        n.b.h  = read_dma_data8(addr + 1);
@@ -962,7 +962,7 @@ uint32_t TOWNS_MEMORY::read_dma_data32(uint32_t addr)
 void TOWNS_MEMORY::write_dma_data8(uint32_t addr, uint32_t data)
 {
        int bank = (addr & addr_mask) >> addr_shift;
-       
+
        __UNLIKELY_IF(wr_table[bank].device != NULL) {
                wr_table[bank].device->write_memory_mapped_io8(addr, data);
        } else {
@@ -973,14 +973,14 @@ void TOWNS_MEMORY::write_dma_data8(uint32_t addr, uint32_t data)
 void TOWNS_MEMORY::write_dma_data16(uint32_t addr, uint32_t data)
 {
        int bank = (addr & addr_mask) >> addr_shift;
-       
+
        __UNLIKELY_IF(wr_table[bank].device != NULL) {
                wr_table[bank].device->write_memory_mapped_io16(addr, data);
        } else {
                uint32_t naddr = addr & bank_mask;
                pair32_t n;
                n.d = data;
-               
+
                __UNLIKELY_IF((naddr + 1) > bank_mask) {
                        wr_table[bank].memory[naddr] = n.b.l;
                        write_dma_data8(addr + 1, n.b.h);
@@ -994,14 +994,14 @@ void TOWNS_MEMORY::write_dma_data16(uint32_t addr, uint32_t data)
 void TOWNS_MEMORY::write_dma_data32(uint32_t addr, uint32_t data)
 {
        int bank = (addr & addr_mask) >> addr_shift;
-       
+
        __UNLIKELY_IF(wr_table[bank].device != NULL) {
                wr_table[bank].device->write_memory_mapped_io32(addr, data);
        } else {
                uint32_t naddr = addr & bank_mask;
                pair32_t n;
                n.d = data;
-               
+
                __UNLIKELY_IF((naddr + 3) > bank_mask) {
                        wr_table[bank].memory[naddr] = n.b.l;
                        write_dma_data8(addr + 1, n.b.h);
@@ -1019,7 +1019,7 @@ void TOWNS_MEMORY::write_dma_data32(uint32_t addr, uint32_t data)
 uint32_t TOWNS_MEMORY::read_dma_data8w(uint32_t addr, int* wait)
 {
        uint32_t val = read_dma_data8(addr);
-       
+
        __LIKELY_IF(wait != NULL) {
                int bank = (addr & addr_mask) >> addr_shift;
                *wait = wr_table[bank].wait;
@@ -1030,7 +1030,7 @@ uint32_t TOWNS_MEMORY::read_dma_data8w(uint32_t addr, int* wait)
 uint32_t TOWNS_MEMORY::read_dma_data16w(uint32_t addr, int* wait)
 {
        uint32_t val = read_dma_data16(addr);
-       
+
        __LIKELY_IF(wait != NULL) {
                int bank = (addr & addr_mask) >> addr_shift;
                *wait = wr_table[bank].wait;
@@ -1041,7 +1041,7 @@ uint32_t TOWNS_MEMORY::read_dma_data16w(uint32_t addr, int* wait)
 uint32_t TOWNS_MEMORY::read_dma_data32w(uint32_t addr, int* wait)
 {
        uint32_t val = read_dma_data32(addr);
-       
+
        __LIKELY_IF(wait != NULL) {
                int bank = (addr & addr_mask) >> addr_shift;
                *wait = wr_table[bank].wait;
@@ -1052,7 +1052,7 @@ uint32_t TOWNS_MEMORY::read_dma_data32w(uint32_t addr, int* wait)
 void TOWNS_MEMORY::write_dma_data8w(uint32_t addr, uint32_t data, int* wait)
 {
        write_dma_data8(addr, data);
-       
+
        __LIKELY_IF(wait != NULL) {
                int bank = (addr & addr_mask) >> addr_shift;
                *wait = wr_table[bank].wait;
@@ -1063,7 +1063,7 @@ void TOWNS_MEMORY::write_dma_data8w(uint32_t addr, uint32_t data, int* wait)
 void TOWNS_MEMORY::write_dma_data16w(uint32_t addr, uint32_t data, int* wait)
 {
        write_dma_data16(addr, data);
-       
+
        __LIKELY_IF(wait != NULL) {
                int bank = (addr & addr_mask) >> addr_shift;
                *wait = wr_table[bank].wait;
@@ -1074,7 +1074,7 @@ void TOWNS_MEMORY::write_dma_data16w(uint32_t addr, uint32_t data, int* wait)
 void TOWNS_MEMORY::write_dma_data32w(uint32_t addr, uint32_t data, int* wait)
 {
        write_dma_data32(addr, data);
-       
+
        __LIKELY_IF(wait != NULL) {
                int bank = (addr & addr_mask) >> addr_shift;
                *wait = wr_table[bank].wait;
@@ -1091,7 +1091,7 @@ void TOWNS_MEMORY::write_signal(int ch, uint32_t data, uint32_t mask)
                        __LIKELY_IF(d_cpu != NULL) {
                                d_cpu->write_signal(SIG_CPU_NMI, data, mask);
                        }
-               }                       
+               }
        } else if(ch == SIG_CPU_NMI) {
                // Check protect
                if(!(nmi_mask)) {
@@ -1163,7 +1163,7 @@ uint32_t TOWNS_MEMORY::read_signal(int ch)
                return 6; // OK?
        } else if(ch == SIG_FMTOWNS_VRAM_WAIT) {
                return (uint32_t)vram_wait_val;
-       } 
+       }
        return 0;
 }
 
@@ -1183,28 +1183,28 @@ bool TOWNS_MEMORY::process_state(FILEIO* state_fio, bool loading)
        if(!state_fio->StateCheckUint32(STATE_VERSION)) {
                return false;
        }
-       
+
        if(!state_fio->StateCheckInt32(this_device_id)) {
                return false;
        }
        state_fio->StateValue(machine_id);
        state_fio->StateValue(cpu_id);
        state_fio->StateValue(is_compatible);
-       
+
        state_fio->StateValue(mem_wait_val);
        state_fio->StateValue(vram_wait_val);
        state_fio->StateValue(wait_register);
-       
+
        state_fio->StateValue(dma_is_vram);
        state_fio->StateValue(nmi_vector_protect);
        state_fio->StateValue(software_reset);
        state_fio->StateValue(poff_status);
        state_fio->StateValue(reset_happened);
-       
+
        state_fio->StateValue(extra_nmi_val);
        state_fio->StateValue(extra_nmi_mask);
        state_fio->StateValue(nmi_mask);
-       
+
        state_fio->StateArray(ram_page0,  sizeof(ram_page0), 1);
        state_fio->StateArray(ram_pagec,  sizeof(ram_pagec), 1);
        state_fio->StateArray(ram_paged,  sizeof(ram_paged), 1);
@@ -1213,7 +1213,7 @@ bool TOWNS_MEMORY::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(select_d0_rom);
        state_fio->StateValue(select_d0_dict);
        state_fio->StateValue(ankcg_enabled);
-       
+
        state_fio->StateValue(vram_wait_val);
        state_fio->StateValue(mem_wait_val);
        state_fio->StateValue(vram_size);
@@ -1221,7 +1221,7 @@ bool TOWNS_MEMORY::process_state(FILEIO* state_fio, bool loading)
 
        if(loading) {
                update_machine_features(); // Update MISC3, MISC4 by MACHINE ID.
-               
+
                uint32_t length_tmp = state_fio->FgetUint32_LE();
                if(extra_ram != NULL) {
                        free(extra_ram);
index 8949ff9..9c6baa4 100644 (file)
 
 #ifndef _I386_H_
 #define _I386_H_
-//#if defined(USE_SHARED_DLL)
-//#if 0
-//#include "libcpu_newdev/i386.h"
-//#else
-//#include "vm.h"
 #include "../emu.h"
 #include "device.h"
 
@@ -76,7 +71,7 @@ public:
                set_device_name(_T("Intel i80x86 CPU"));
        }
        ~I386() {}
-       
+
        // common functions
        void initialize();
        void release();
@@ -130,7 +125,7 @@ public:
        int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0);
 //#endif
        bool process_state(FILEIO* state_fio, bool loading);
-       
+
        // unique function
        void set_context_extreset(DEVICE* device, int id, uint32_t mask)
        {
index ce18f2a..460bc23 100644 (file)
@@ -365,23 +365,37 @@ int I386::run(int cycles)
                                if(device_dma != NULL) device_dma->do_dma();
                        }
 //#endif
-                       passed_cycles = max(5, extra_cycles); // 80386 CPI: 4.9
-                       extra_cycles = 0;
+                       // 80386 CPI: 4.9
+                       int __cycles = 5;
+                       if(extra_cycles > 0) {
+                               __cycles += extra_cycles;
+                               extra_cycles = 0;
+                       }
+                       __UNLIKELY_IF(_USE_DEBUGGER) {
+                               total_cycles += __cycles;
+                       }
+                       cpu_wait(5, i386_memory_wait);
+                       return __cycles;
                } else {
                        // run only one opcode
-                       passed_cycles = extra_cycles;
-                       extra_cycles = 0;
-                       passed_cycles += run_one_opecode();
+                       int __cycles = run_one_opecode();
+                       int tmp_extra_cycles = 0;
+                       if(extra_cycles > 0) {
+                               tmp_extra_cycles = extra_cycles;
+                               extra_cycles = 0;
+                       }
+                       __UNLIKELY_IF(_USE_DEBUGGER) {
+                               total_cycles += __cycles;
+                       }
+                       cpu_wait(__cycles, i386_memory_wait);
+                       return __cycles + tmp_extra_cycles;
                }
 //#ifdef USE_DEBUGGER
-               __UNLIKELY_IF(_USE_DEBUGGER) {
-                       total_cycles += passed_cycles;
-               }
 //#endif
-               cpu_wait(passed_cycles, i386_memory_wait);
-               return passed_cycles;
        } else {
-               remained_cycles += cycles + extra_cycles;
+               // Secondary
+//             remained_cycles += cycles + extra_cycles;
+               remained_cycles += cycles;
                extra_cycles = 0;
                int first_cycles = remained_cycles;
 
@@ -403,7 +417,7 @@ int I386::run(int cycles)
                        remained_cycles = 0;
                }
                int passed_cycles = first_cycles - remained_cycles;
-               cpu_wait(passed_cycles, i386_memory_wait);
+               //cpu_wait(passed_cycles, i386_memory_wait);
                return passed_cycles;
        }
 }
index ff60737..246ff61 100644 (file)
@@ -56,7 +56,7 @@ class  DLL_PREFIX I386 : public DEVICE
 private:
        DEVICE *device_pic;
        outputs_t outputs_extreset;
-       
+
 //#ifdef USE_DEBUGGER
 //     DEBUGGER *device_debugger;
        DEVICE *device_mem_stored;
@@ -70,12 +70,12 @@ private:
        uint32_t PREV_CS_BASE;
        uint32_t waitfactor;
        int64_t waitcount;
-       
+
        bool _USE_DEBUGGER;
        bool _I86_PSEUDO_BIOS;
        bool _SINGLE_MODE_DMA;
        uint32_t address_mask;
-       
+
        int run_one_opecode();
        uint32_t __FASTCALL convert_address(uint32_t cs, uint32_t eip);
        inline void __FASTCALL cpu_wait(int clocks, int64_t& memory_wait);
@@ -95,7 +95,7 @@ public:
                device_model = DEFAULT;
        }
        ~I386() {}
-       
+
        // common functions
        void initialize();
        void release();
@@ -148,7 +148,7 @@ public:
        virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0);
 //#endif
        bool process_state(FILEIO* state_fio, bool loading);
-       
+
        // unique function
        void set_context_mem(DEVICE* device);
 //     {
@@ -193,7 +193,10 @@ public:
 inline void __FASTCALL I386::cpu_wait(int clocks, int64_t& memory_wait)
 {
        __UNLIKELY_IF(clocks < 0) {
-               clocks = 0;
+               return;
+       }
+       __LIKELY_IF(waitfactor <= 65536) {
+               return;
        }
        int64_t wfactor = waitfactor;
        int64_t wcount = waitcount;
index 2d0cb9a..cb0d14a 100644 (file)
 #ifndef _MC6809_H_
 #define _MC6809_H_
 
-//#if defined(USE_SHARED_DLL)
-//#if 0
-//#include "libcpu_newdev/libcpu_mc6809/mc6809.h"
-//#else
-//#include "vm.h"
-//#include "../emu.h"
 #include "device.h"
 #include "mc6809_consts.h"
 
@@ -56,10 +50,10 @@ protected:
        pair32_t x, y;  /* Index registers */
        uint8_t cc;
        pair32_t ea;    /* effective address */
-       
+
        uint32_t int_state;
        /* In Motorola's datasheet, status has some valiants. 20171207 K.O */
-       
+
        bool req_halt_on;
        bool req_halt_off;
        bool busreq;
@@ -72,7 +66,7 @@ protected:
        int icount;
        int extra_icount;
        bool __USE_DEBUGGER;
-       
+
        uint64_t cycles_tmp_count;
        uint32_t insns_count;
        uint32_t extra_tmp_count;
@@ -104,7 +98,7 @@ protected:
                CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
                CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N
        };
-       
+
 /* decrement */
        const uint8_t flags8d[256] = {
                CC_Z,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
@@ -124,11 +118,11 @@ protected:
                CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,
                CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N,CC_N
        };
-       
+
        /* FIXME: Cycles differ slighly from hd6309 emulation */
        const int index_cycle_em[256] = {       /* Index Loopup cycle counts */
 /*           0xX0, 0xX1, 0xX2, 0xX3, 0xX4, 0xX5, 0xX6, 0xX7, 0xX8, 0xX9, 0xXA, 0xXB, 0xXC, 0xXD, 0xXE, 0xXF */
-               
+
                /* 0x0X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                /* 0x1X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                /* 0x2X */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -146,7 +140,7 @@ protected:
 /* 0xEX */ 2, 3, 2, 3, 0, 1, 1, 1, 1, 4, 0, 4, 1, 5, 0, 2,
                /* 0xFX */ 4, 6, 5, 6, 3, 4, 4, 4, 4, 7, 3, 7, 4, 8, 3, 5
        };
-       
+
        /* timings for 1-byte opcodes */
        /* 20100731 Fix to XM7 */
        const int cycles1[256] = {
@@ -178,15 +172,15 @@ protected:
        void __FASTCALL cpu_firq_fetch_vector_address(void);
        void __FASTCALL cpu_nmi_fetch_vector_address(void);
        void __FASTCALL cpu_wait(int clocks = 1);
-       
+
        // Useful routines.
        inline void __FASTCALL BRANCH(bool cond);
        inline void __FASTCALL LBRANCH(bool cond);
-       
+
        inline pair32_t __FASTCALL RM16_PAIR(uint32_t addr);
        inline uint8_t __FASTCALL GET_INDEXED_DATA(void);
        inline pair32_t __FASTCALL GET_INDEXED_DATA16(void);
-       
+
        inline void __FASTCALL  NEG_MEM(uint8_t a_neg);
        inline uint8_t __FASTCALL NEG_REG(uint8_t r_neg);
        inline void __FASTCALL  COM_MEM(uint8_t a_neg);
@@ -212,7 +206,7 @@ protected:
        inline uint8_t __FASTCALL CLC_REG(uint8_t r_neg);
        inline void __FASTCALL  CLR_MEM(uint8_t a_neg);
        inline uint8_t __FASTCALL CLR_REG(uint8_t r_neg);
-       
+
        inline uint8_t __FASTCALL SUB8_REG(uint8_t reg, uint8_t data);
        inline uint8_t __FASTCALL CMP8_REG(uint8_t reg, uint8_t data);
        inline uint8_t __FASTCALL SBC8_REG(uint8_t reg, uint8_t data);
@@ -230,7 +224,7 @@ protected:
        inline uint16_t CMP16_REG(uint16_t reg, uint16_t data);
        inline uint16_t LOAD16_REG(uint16_t reg);
        inline void __FASTCALL STORE16_REG(pair32_t *p);
-       
+
        // Instructions.
        void __FASTCALL abx();
        void __FASTCALL adca_di();
@@ -465,8 +459,8 @@ protected:
        void __FASTCALL ror_ex();
        void __FASTCALL ror_ix();
        void __FASTCALL rst();
-       void __FASTCALL rti();  
-       void __FASTCALL rts();  
+       void __FASTCALL rti();
+       void __FASTCALL rts();
        void __FASTCALL sbca_di();
        void __FASTCALL sbca_ex();
        void __FASTCALL sbca_im();
@@ -536,9 +530,9 @@ protected:
 
        virtual uint32_t cpu_disassemble_m6809(_TCHAR *buffer, uint32_t pc, const uint8_t *oprom, const uint8_t *opram);
        virtual void __FASTCALL debugger_hook(void);
-       
+
 public:
-       MC6809(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) 
+       MC6809(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu)
        {
 
                total_icount = prev_total_icount = 0;
@@ -549,23 +543,23 @@ public:
                for(int i = 0; i < 0x100; i++) {
                        m6809_main[i] = &MC6809::nop;
                }
-               
+
                initialize_output_signals(&outputs_bus_ba);
                initialize_output_signals(&outputs_bus_bs);
                set_device_name(_T("MC6809 MPU"));
        }
        ~MC6809() {}
-       
+
        // common functions
        virtual void initialize();
        virtual void reset();
        void event_frame();
-       
+
        int __FASTCALL run(int clock);
-       
+
        virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask);
        virtual bool process_state(FILEIO* state_fio, bool loading);
-       
+
        void __FASTCALL set_extra_clock(int clock)
        {
                extra_icount += clock;
@@ -575,7 +569,7 @@ public:
                return extra_icount;
        }
 
-       
+
        bool is_cpu()
        {
                return true;
@@ -598,20 +592,20 @@ public:
        }
        void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data);
        uint32_t __FASTCALL read_debug_data8(uint32_t addr);
-       
+
        void __FASTCALL write_debug_data16(uint32_t addr, uint32_t data)
        {
                write_debug_data8(addr, (data >> 8) & 0xff);
                write_debug_data8(addr + 1, data & 0xff);
        }
-       
+
        uint32_t __FASTCALL read_debug_data16(uint32_t addr)
        {
                uint32_t val = read_debug_data8(addr) << 8;
                val |= read_debug_data8(addr + 1);
                return val;
        }
-       
+
        void __FASTCALL write_debug_data32(uint32_t addr, uint32_t data)
        {
                write_debug_data16(addr, (data >> 16) & 0xffff);
@@ -623,29 +617,29 @@ public:
                val |= read_debug_data16(addr + 2);
                return val;
        }
-       
+
        void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data);
        uint32_t __FASTCALL read_debug_io8(uint32_t addr);
-       
+
        void __FASTCALL write_debug_io16(uint32_t addr, uint32_t data)
        {
                write_debug_io8(addr, (data >> 8) & 0xff);
                write_debug_io8(addr + 1, data & 0xff);
        }
-       
+
        uint32_t __FASTCALL read_debug_io16(uint32_t addr)
        {
                uint32_t val = read_debug_io8(addr) << 8;
                val |= read_debug_io8(addr + 1);
                return val;
        }
-       
+
        void __FASTCALL write_debug_io32(uint32_t addr, uint32_t data)
        {
                write_debug_io16(addr, (data >> 16) & 0xffff);
                write_debug_io16(addr + 2, data & 0xffff);
        }
-       
+
        uint32_t __FASTCALL read_debug_io32(uint32_t addr)
        {
                uint32_t val = read_debug_io16(addr) << 16;
@@ -720,4 +714,3 @@ public:
 
 };
 #endif
-
index 47a548b..1511984 100644 (file)
        } \
 } while(0)
 
-#define UPDATE_EXTRA_EVENT(clock) do { \
+#define CLOCK_IN_OP(clock) do { \
        if(is_primary) { \
-               if(busreq) { \
-                       busreq_icount += (clock); \
+               if(wait || wait_icount > 0) { \
+                       wait_icount += (clock); \
                } \
-               update_extra_event(clock); \
+               event_icount += (clock); \
        } \
 } while(0)
 
-#define POP(DR) do { \
-       RM16(SPD, &DR); \
-       SP += 2; \
+#define UPDATE_EVENT_IN_OP(clock) do { \
+       if(is_primary ) { \
+               if(wait || wait_icount > 0) { \
+                       wait_icount += (clock); \
+               } \
+               event_icount += (clock); \
+               if(!(wait || wait_icount > 0)) { \
+                       update_event_in_opecode(event_icount); \
+                       event_done_icount += event_icount; \
+                       event_icount = 0; \
+               } \
+       } \
 } while(0)
 
-#define PUSH(SR) do { \
-       SP -= 2; \
-       WM16(SPD, &SR); \
-} while(0)
 
-Z80_INLINE uint8_t __FASTCALL Z80::RM8(uint32_t addr)
+Z80_INLINE uint8_t  Z80::RM8(uint32_t addr)
 {
 //#ifdef Z80_MEMORY_WAIT
-       UPDATE_EXTRA_EVENT(1);
+       UPDATE_EVENT_IN_OP(2);
        if(has_memory_wait) {
-               int wait;
-               uint8_t val = d_mem->read_data8w(addr, &wait);
-               icount -= wait;
-               UPDATE_EXTRA_EVENT(2 + wait);
+               int wait_clock;
+               uint8_t val = d_mem->read_data8w(addr, &wait_clock);
+               icount -= wait_clock;
+               CLOCK_IN_OP(1 + wait_clock);
                return val;
        } else {
 //#else
                uint8_t val = d_mem->read_data8(addr);
-               UPDATE_EXTRA_EVENT(2);
+               CLOCK_IN_OP(1);
                return val;
        }
 //#endif
 }
 
-Z80_INLINE void __FASTCALL Z80::WM8(uint32_t addr, uint8_t val)
+Z80_INLINE void  Z80::WM8(uint32_t addr, uint8_t val)
 {
 //#ifdef Z80_MEMORY_WAIT
-       UPDATE_EXTRA_EVENT(1);
+       UPDATE_EVENT_IN_OP(2);
        if(has_memory_wait) {
-               int wait;
-               d_mem->write_data8w(addr, val, &wait);
-               icount -= wait;
-               UPDATE_EXTRA_EVENT(2 + wait);
+               int wait_clock;
+               d_mem->write_data8w(addr, val, &wait_clock);
+               icount -= wait_clock;
+               CLOCK_IN_OP(1 + wait_clock);
        } else {
 //#else
                d_mem->write_data8(addr, val);
-               UPDATE_EXTRA_EVENT(2);
+               CLOCK_IN_OP(1);
        }
 //#endif
 }
 
-Z80_INLINE void __FASTCALL Z80::RM16(uint32_t addr, pair32_t *r)
+Z80_INLINE void  Z80::RM16(uint32_t addr, pair32_t *r)
 {
        r->b.l = RM8(addr);
        r->b.h = RM8((addr + 1) & 0xffff);
 }
 
-Z80_INLINE void __FASTCALL Z80::WM16(uint32_t addr, pair32_t *r)
+Z80_INLINE void  Z80::WM16(uint32_t addr, pair32_t *r)
 {
        WM8(addr, r->b.l);
        WM8((addr + 1) & 0xffff, r->b.h);
 }
 
-Z80_INLINE uint8_t __FASTCALL Z80::FETCHOP()
+Z80_INLINE uint8_t  Z80::FETCHOP()
 {
        unsigned pctmp = PCD;
        PC++;
        R++;
-       
+
        // consider m1 cycle wait
-       UPDATE_EXTRA_EVENT(1);
-       int wait;
-       uint8_t val = d_mem->fetch_op(pctmp, &wait);
-       icount -= wait;
-       UPDATE_EXTRA_EVENT(3 + wait);
+       UPDATE_EVENT_IN_OP(2);
+       int wait_clock;
+       uint8_t val = d_mem->fetch_op(pctmp, &wait_clock);
+       icount -= wait_clock;
+       CLOCK_IN_OP(2 + wait_clock);
        return val;
 }
 
-Z80_INLINE uint8_t __FASTCALL Z80::FETCH8()
+Z80_INLINE uint8_t  Z80::FETCH8()
 {
        unsigned pctmp = PCD;
        PC++;
        return RM8(pctmp);
 }
 
-Z80_INLINE uint32_t __FASTCALL Z80::FETCH16()
+Z80_INLINE uint32_t  Z80::FETCH16()
 {
        unsigned pctmp = PCD;
        PC += 2;
        return RM8(pctmp) | ((uint32_t)RM8((pctmp + 1) & 0xffff) << 8);
 }
 
-Z80_INLINE uint8_t __FASTCALL Z80::IN8(uint32_t addr)
+Z80_INLINE uint8_t  Z80::IN8(uint32_t addr)
 {
 //#ifdef Z80_IO_WAIT
-       UPDATE_EXTRA_EVENT(2);
+       UPDATE_EVENT_IN_OP(3);
        if(has_io_wait) {
-               int wait;
-               uint8_t val = d_io->read_io8w(addr, &wait);
-               icount -= wait;
-               UPDATE_EXTRA_EVENT(2 + wait);
+               int wait_clock;
+               uint8_t val = d_io->read_io8w(addr, &wait_clock);
+               icount -= wait_clock;
+               CLOCK_IN_OP(1 + wait_clock);
                return val;
        } else {
 //#else
                uint8_t val = d_io->read_io8(addr);
-               UPDATE_EXTRA_EVENT(2);
+               CLOCK_IN_OP(1);
                return val;
        }
 //#endif
 }
 
-Z80_INLINE void __FASTCALL Z80::OUT8(uint32_t addr, uint8_t val)
+Z80_INLINE void  Z80::OUT8(uint32_t addr, uint8_t val)
 {
 //#ifdef HAS_NSC800
-       UPDATE_EXTRA_EVENT(2);
+       UPDATE_EVENT_IN_OP(3);
        if(has_nsc800) {
                if((addr & 0xff) == 0xbb) {
                        icr = val;
-                       UPDATE_EXTRA_EVENT(2);
+                       CLOCK_IN_OP(1);
                        return;
                }
        }
 //#endif
 //#ifdef Z80_IO_WAIT
        if(has_io_wait) {
-               int wait;
-               d_io->write_io8w(addr, val, &wait);
-               icount -= wait;
-               UPDATE_EXTRA_EVENT(2 + wait);
+               int wait_clock;
+               d_io->write_io8w(addr, val, &wait_clock);
+               icount -= wait_clock;
+               CLOCK_IN_OP(1 + wait_clock);
        } else {
 //#else
                d_io->write_io8(addr, val);
-               UPDATE_EXTRA_EVENT(2);
+               CLOCK_IN_OP(1);
        }
 //#endif
 }
@@ -274,6 +279,7 @@ Z80_INLINE void __FASTCALL Z80::OUT8(uint32_t addr, uint8_t val)
 
 #define PUSH(SR) do { \
        SP -= 2; \
+       CLOCK_IN_OP(1); \
        WM16(SPD, &SR); \
 } while(0)
 
@@ -371,7 +377,7 @@ Z80_INLINE void __FASTCALL Z80::OUT8(uint32_t addr, uint8_t val)
        WZ = PC; \
 } while(0)
 
-Z80_INLINE uint8_t __FASTCALL Z80::INC(uint8_t value)
+Z80_INLINE uint8_t  Z80::INC(uint8_t value)
 {
        uint8_t res = value + 1;
        F = (F & CF) | SZHV_inc[res];
@@ -413,6 +419,7 @@ Z80_INLINE uint8_t Z80::DEC(uint8_t value)
 #define RRD() do { \
        uint8_t n = RM8(HL); \
        WZ = HL + 1; \
+       CLOCK_IN_OP(4); \
        WM8(HL, (n >> 4) | (A << 4)); \
        A = (A & 0xf0) | (n & 0x0f); \
        F = (F & CF) | SZP[A]; \
@@ -421,6 +428,7 @@ Z80_INLINE uint8_t Z80::DEC(uint8_t value)
 #define RLD() do { \
        uint8_t n = RM8(HL); \
        WZ = HL + 1; \
+       CLOCK_IN_OP(4); \
        WM8(HL, (n << 4) | (A & 0x0f)); \
        A = (A & 0xf0) | (n >> 4); \
        F = (F & CF) | SZP[A]; \
@@ -516,7 +524,9 @@ Z80_INLINE uint8_t Z80::DEC(uint8_t value)
        pair32_t tmp; \
        tmp.d = 0; \
        RM16(SPD, &tmp); \
+       CLOCK_IN_OP(1); \
        WM16(SPD, &DR); \
+       CLOCK_IN_OP(2); \
        DR = tmp; \
        WZ = DR.d; \
 } while(0)
@@ -542,7 +552,7 @@ Z80_INLINE uint8_t Z80::DEC(uint8_t value)
        HL = (uint16_t)res; \
 } while(0)
 
-Z80_INLINE uint8_t __FASTCALL Z80::RLC(uint8_t value)
+Z80_INLINE uint8_t  Z80::RLC(uint8_t value)
 {
        unsigned res = value;
        unsigned c = (res & 0x80) ? CF : 0;
@@ -551,7 +561,7 @@ Z80_INLINE uint8_t __FASTCALL Z80::RLC(uint8_t value)
        return res;
 }
 
-Z80_INLINE uint8_t __FASTCALL Z80::RRC(uint8_t value)
+Z80_INLINE uint8_t  Z80::RRC(uint8_t value)
 {
        unsigned res = value;
        unsigned c = (res & 0x01) ? CF : 0;
@@ -560,7 +570,7 @@ Z80_INLINE uint8_t __FASTCALL Z80::RRC(uint8_t value)
        return res;
 }
 
-Z80_INLINE uint8_t __FASTCALL Z80::RL(uint8_t value)
+Z80_INLINE uint8_t  Z80::RL(uint8_t value)
 {
        unsigned res = value;
        unsigned c = (res & 0x80) ? CF : 0;
@@ -569,7 +579,7 @@ Z80_INLINE uint8_t __FASTCALL Z80::RL(uint8_t value)
        return res;
 }
 
-Z80_INLINE uint8_t __FASTCALL Z80::RR(uint8_t value)
+Z80_INLINE uint8_t  Z80::RR(uint8_t value)
 {
        unsigned res = value;
        unsigned c = (res & 0x01) ? CF : 0;
@@ -578,7 +588,7 @@ Z80_INLINE uint8_t __FASTCALL Z80::RR(uint8_t value)
        return res;
 }
 
-Z80_INLINE uint8_t __FASTCALL Z80::SLA(uint8_t value)
+Z80_INLINE uint8_t  Z80::SLA(uint8_t value)
 {
        unsigned res = value;
        unsigned c = (res & 0x80) ? CF : 0;
@@ -587,7 +597,7 @@ Z80_INLINE uint8_t __FASTCALL Z80::SLA(uint8_t value)
        return res;
 }
 
-Z80_INLINE uint8_t __FASTCALL Z80::SRA(uint8_t value)
+Z80_INLINE uint8_t  Z80::SRA(uint8_t value)
 {
        unsigned res = value;
        unsigned c = (res & 0x01) ? CF : 0;
@@ -596,7 +606,7 @@ Z80_INLINE uint8_t __FASTCALL Z80::SRA(uint8_t value)
        return res;
 }
 
-Z80_INLINE uint8_t __FASTCALL Z80::SLL(uint8_t value)
+Z80_INLINE uint8_t  Z80::SLL(uint8_t value)
 {
        unsigned res = value;
        unsigned c = (res & 0x80) ? CF : 0;
@@ -605,7 +615,7 @@ Z80_INLINE uint8_t __FASTCALL Z80::SLL(uint8_t value)
        return res;
 }
 
-Z80_INLINE uint8_t __FASTCALL Z80::SRL(uint8_t value)
+Z80_INLINE uint8_t  Z80::SRL(uint8_t value)
 {
        unsigned res = value;
        unsigned c = (res & 0x01) ? CF : 0;
@@ -626,12 +636,12 @@ Z80_INLINE uint8_t __FASTCALL Z80::SRL(uint8_t value)
        F = (F & CF) | HF | (SZ_BIT[reg & (1 << bit)] & ~(YF | XF)) | ((ea >> 8) & (YF | XF)); \
 } while(0)
 
-Z80_INLINE uint8_t __FASTCALL Z80::RES(uint8_t bit, uint8_t value)
+Z80_INLINE uint8_t  Z80::RES(uint8_t bit, uint8_t value)
 {
        return value & ~(1 << bit);
 }
 
-Z80_INLINE uint8_t __FASTCALL Z80::SET(uint8_t bit, uint8_t value)
+Z80_INLINE uint8_t Z80::SET(uint8_t bit, uint8_t value)
 {
        return value | (1 << bit);
 }
@@ -644,6 +654,7 @@ Z80_INLINE uint8_t __FASTCALL Z80::SET(uint8_t bit, uint8_t value)
        if((A + io) & 0x08) F |= XF; /* bit 3 -> flag 3 */ \
        HL++; DE++; BC--; \
        if(BC) F |= VF; \
+       CLOCK_IN_OP(2); \
 } while(0)
 
 #define CPI() do { \
@@ -656,31 +667,32 @@ Z80_INLINE uint8_t __FASTCALL Z80::SET(uint8_t bit, uint8_t value)
        if(res & 0x02) F |= YF; /* bit 1 -> flag 5 */ \
        if(res & 0x08) F |= XF; /* bit 3 -> flag 3 */ \
        if(BC) F |= VF; \
+       CLOCK_IN_OP(5); \
 } while(0)
 
 #define INI() do { \
-       unsigned t; \
+       CLOCK_IN_OP(1); \
        uint8_t io = IN8(BC); \
        WZ = BC + 1; \
        B--; \
        WM8(HL, io); \
        HL++; \
        F = SZ[B]; \
-       t = (unsigned)((C + 1) & 0xff) + (unsigned)io; \
+       unsigned t = (unsigned)((C + 1) & 0xff) + (unsigned)io; \
        if(io & SF) F |= NF; \
        if(t & 0x100) F |= HF | CF; \
        F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; \
 } while(0)
 
 #define OUTI() do { \
-       unsigned t; \
+       CLOCK_IN_OP(1); \
        uint8_t io = RM8(HL); \
        B--; \
        WZ = BC + 1; \
        OUT8(BC, io); \
        HL++; \
        F = SZ[B]; \
-       t = (unsigned)L + (unsigned)io; \
+       unsigned t = (unsigned)L + (unsigned)io;        \
        if(io & SF) F |= NF; \
        if(t & 0x100) F |= HF | CF; \
        F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; \
@@ -694,6 +706,7 @@ Z80_INLINE uint8_t __FASTCALL Z80::SET(uint8_t bit, uint8_t value)
        if((A + io) & 0x08) F |= XF; /* bit 3 -> flag 3 */ \
        HL--; DE--; BC--; \
        if(BC) F |= VF; \
+       CLOCK_IN_OP(2); \
 } while(0)
 
 #define CPD() do { \
@@ -706,31 +719,32 @@ Z80_INLINE uint8_t __FASTCALL Z80::SET(uint8_t bit, uint8_t value)
        if(res & 0x02) F |= YF; /* bit 1 -> flag 5 */ \
        if(res & 0x08) F |= XF; /* bit 3 -> flag 3 */ \
        if(BC) F |= VF; \
+       CLOCK_IN_OP(5); \
 } while(0)
 
 #define IND() do { \
-       unsigned t; \
+       CLOCK_IN_OP(1); \
        uint8_t io = IN8(BC); \
        WZ = BC - 1; \
        B--; \
        WM8(HL, io); \
        HL--; \
        F = SZ[B]; \
-       t = ((unsigned)(C - 1) & 0xff) + (unsigned)io; \
+       unsigned t = ((unsigned)(C - 1) & 0xff) + (unsigned)io; \
        if(io & SF) F |= NF; \
        if(t & 0x100) F |= HF | CF; \
        F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; \
 } while(0)
 
 #define OUTD() do { \
-       unsigned t; \
+       CLOCK_IN_OP(1); \
        uint8_t io = RM8(HL); \
        B--; \
        WZ = BC - 1; \
        OUT8(BC, io); \
        HL--; \
        F = SZ[B]; \
-       t = (unsigned)L + (unsigned)io; \
+       unsigned t = (unsigned)L + (unsigned)io; \
        if(io & SF) F |= NF; \
        if(t & 0x100) F |= HF | CF; \
        F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; \
@@ -811,532 +825,539 @@ Z80_INLINE uint8_t __FASTCALL Z80::SET(uint8_t bit, uint8_t value)
 
 void Z80::OP_CB(uint8_t code)
 {
+       // Done: M1 + M1
+       uint8_t v;
+
        icount -= cc_cb[code];
-       
+
        switch(code) {
-       case 0x00: B = RLC(B); break;                   /* RLC  B           */
-       case 0x01: C = RLC(C); break;                   /* RLC  C           */
-       case 0x02: D = RLC(D); break;                   /* RLC  D           */
-       case 0x03: E = RLC(E); break;                   /* RLC  E           */
-       case 0x04: H = RLC(H); break;                   /* RLC  H           */
-       case 0x05: L = RLC(L); break;                   /* RLC  L           */
-       case 0x06: WM8(HL, RLC(RM8(HL))); break;        /* RLC  (HL)        */
-       case 0x07: A = RLC(A); break;                   /* RLC  A           */
-       case 0x08: B = RRC(B); break;                   /* RRC  B           */
-       case 0x09: C = RRC(C); break;                   /* RRC  C           */
-       case 0x0a: D = RRC(D); break;                   /* RRC  D           */
-       case 0x0b: E = RRC(E); break;                   /* RRC  E           */
-       case 0x0c: H = RRC(H); break;                   /* RRC  H           */
-       case 0x0d: L = RRC(L); break;                   /* RRC  L           */
-       case 0x0e: WM8(HL, RRC(RM8(HL))); break;        /* RRC  (HL)        */
-       case 0x0f: A = RRC(A); break;                   /* RRC  A           */
-       case 0x10: B = RL(B); break;                    /* RL   B           */
-       case 0x11: C = RL(C); break;                    /* RL   C           */
-       case 0x12: D = RL(D); break;                    /* RL   D           */
-       case 0x13: E = RL(E); break;                    /* RL   E           */
-       case 0x14: H = RL(H); break;                    /* RL   H           */
-       case 0x15: L = RL(L); break;                    /* RL   L           */
-       case 0x16: WM8(HL, RL(RM8(HL))); break;         /* RL   (HL)        */
-       case 0x17: A = RL(A); break;                    /* RL   A           */
-       case 0x18: B = RR(B); break;                    /* RR   B           */
-       case 0x19: C = RR(C); break;                    /* RR   C           */
-       case 0x1a: D = RR(D); break;                    /* RR   D           */
-       case 0x1b: E = RR(E); break;                    /* RR   E           */
-       case 0x1c: H = RR(H); break;                    /* RR   H           */
-       case 0x1d: L = RR(L); break;                    /* RR   L           */
-       case 0x1e: WM8(HL, RR(RM8(HL))); break;         /* RR   (HL)        */
-       case 0x1f: A = RR(A); break;                    /* RR   A           */
-       case 0x20: B = SLA(B); break;                   /* SLA  B           */
-       case 0x21: C = SLA(C); break;                   /* SLA  C           */
-       case 0x22: D = SLA(D); break;                   /* SLA  D           */
-       case 0x23: E = SLA(E); break;                   /* SLA  E           */
-       case 0x24: H = SLA(H); break;                   /* SLA  H           */
-       case 0x25: L = SLA(L); break;                   /* SLA  L           */
-       case 0x26: WM8(HL, SLA(RM8(HL))); break;        /* SLA  (HL)        */
-       case 0x27: A = SLA(A); break;                   /* SLA  A           */
-       case 0x28: B = SRA(B); break;                   /* SRA  B           */
-       case 0x29: C = SRA(C); break;                   /* SRA  C           */
-       case 0x2a: D = SRA(D); break;                   /* SRA  D           */
-       case 0x2b: E = SRA(E); break;                   /* SRA  E           */
-       case 0x2c: H = SRA(H); break;                   /* SRA  H           */
-       case 0x2d: L = SRA(L); break;                   /* SRA  L           */
-       case 0x2e: WM8(HL, SRA(RM8(HL))); break;        /* SRA  (HL)        */
-       case 0x2f: A = SRA(A); break;                   /* SRA  A           */
-       case 0x30: B = SLL(B); break;                   /* SLL  B           */
-       case 0x31: C = SLL(C); break;                   /* SLL  C           */
-       case 0x32: D = SLL(D); break;                   /* SLL  D           */
-       case 0x33: E = SLL(E); break;                   /* SLL  E           */
-       case 0x34: H = SLL(H); break;                   /* SLL  H           */
-       case 0x35: L = SLL(L); break;                   /* SLL  L           */
-       case 0x36: WM8(HL, SLL(RM8(HL))); break;        /* SLL  (HL)        */
-       case 0x37: A = SLL(A); break;                   /* SLL  A           */
-       case 0x38: B = SRL(B); break;                   /* SRL  B           */
-       case 0x39: C = SRL(C); break;                   /* SRL  C           */
-       case 0x3a: D = SRL(D); break;                   /* SRL  D           */
-       case 0x3b: E = SRL(E); break;                   /* SRL  E           */
-       case 0x3c: H = SRL(H); break;                   /* SRL  H           */
-       case 0x3d: L = SRL(L); break;                   /* SRL  L           */
-       case 0x3e: WM8(HL, SRL(RM8(HL))); break;        /* SRL  (HL)        */
-       case 0x3f: A = SRL(A); break;                   /* SRL  A           */
-       case 0x40: BIT(0, B); break;                    /* BIT  0,B         */
-       case 0x41: BIT(0, C); break;                    /* BIT  0,C         */
-       case 0x42: BIT(0, D); break;                    /* BIT  0,D         */
-       case 0x43: BIT(0, E); break;                    /* BIT  0,E         */
-       case 0x44: BIT(0, H); break;                    /* BIT  0,H         */
-       case 0x45: BIT(0, L); break;                    /* BIT  0,L         */
-       case 0x46: BIT_HL(0, RM8(HL)); break;           /* BIT  0,(HL)      */
-       case 0x47: BIT(0, A); break;                    /* BIT  0,A         */
-       case 0x48: BIT(1, B); break;                    /* BIT  1,B         */
-       case 0x49: BIT(1, C); break;                    /* BIT  1,C         */
-       case 0x4a: BIT(1, D); break;                    /* BIT  1,D         */
-       case 0x4b: BIT(1, E); break;                    /* BIT  1,E         */
-       case 0x4c: BIT(1, H); break;                    /* BIT  1,H         */
-       case 0x4d: BIT(1, L); break;                    /* BIT  1,L         */
-       case 0x4e: BIT_HL(1, RM8(HL)); break;           /* BIT  1,(HL)      */
-       case 0x4f: BIT(1, A); break;                    /* BIT  1,A         */
-       case 0x50: BIT(2, B); break;                    /* BIT  2,B         */
-       case 0x51: BIT(2, C); break;                    /* BIT  2,C         */
-       case 0x52: BIT(2, D); break;                    /* BIT  2,D         */
-       case 0x53: BIT(2, E); break;                    /* BIT  2,E         */
-       case 0x54: BIT(2, H); break;                    /* BIT  2,H         */
-       case 0x55: BIT(2, L); break;                    /* BIT  2,L         */
-       case 0x56: BIT_HL(2, RM8(HL)); break;           /* BIT  2,(HL)      */
-       case 0x57: BIT(2, A); break;                    /* BIT  2,A         */
-       case 0x58: BIT(3, B); break;                    /* BIT  3,B         */
-       case 0x59: BIT(3, C); break;                    /* BIT  3,C         */
-       case 0x5a: BIT(3, D); break;                    /* BIT  3,D         */
-       case 0x5b: BIT(3, E); break;                    /* BIT  3,E         */
-       case 0x5c: BIT(3, H); break;                    /* BIT  3,H         */
-       case 0x5d: BIT(3, L); break;                    /* BIT  3,L         */
-       case 0x5e: BIT_HL(3, RM8(HL)); break;           /* BIT  3,(HL)      */
-       case 0x5f: BIT(3, A); break;                    /* BIT  3,A         */
-       case 0x60: BIT(4, B); break;                    /* BIT  4,B         */
-       case 0x61: BIT(4, C); break;                    /* BIT  4,C         */
-       case 0x62: BIT(4, D); break;                    /* BIT  4,D         */
-       case 0x63: BIT(4, E); break;                    /* BIT  4,E         */
-       case 0x64: BIT(4, H); break;                    /* BIT  4,H         */
-       case 0x65: BIT(4, L); break;                    /* BIT  4,L         */
-       case 0x66: BIT_HL(4, RM8(HL)); break;           /* BIT  4,(HL)      */
-       case 0x67: BIT(4, A); break;                    /* BIT  4,A         */
-       case 0x68: BIT(5, B); break;                    /* BIT  5,B         */
-       case 0x69: BIT(5, C); break;                    /* BIT  5,C         */
-       case 0x6a: BIT(5, D); break;                    /* BIT  5,D         */
-       case 0x6b: BIT(5, E); break;                    /* BIT  5,E         */
-       case 0x6c: BIT(5, H); break;                    /* BIT  5,H         */
-       case 0x6d: BIT(5, L); break;                    /* BIT  5,L         */
-       case 0x6e: BIT_HL(5, RM8(HL)); break;           /* BIT  5,(HL)      */
-       case 0x6f: BIT(5, A); break;                    /* BIT  5,A         */
-       case 0x70: BIT(6, B); break;                    /* BIT  6,B         */
-       case 0x71: BIT(6, C); break;                    /* BIT  6,C         */
-       case 0x72: BIT(6, D); break;                    /* BIT  6,D         */
-       case 0x73: BIT(6, E); break;                    /* BIT  6,E         */
-       case 0x74: BIT(6, H); break;                    /* BIT  6,H         */
-       case 0x75: BIT(6, L); break;                    /* BIT  6,L         */
-       case 0x76: BIT_HL(6, RM8(HL)); break;           /* BIT  6,(HL)      */
-       case 0x77: BIT(6, A); break;                    /* BIT  6,A         */
-       case 0x78: BIT(7, B); break;                    /* BIT  7,B         */
-       case 0x79: BIT(7, C); break;                    /* BIT  7,C         */
-       case 0x7a: BIT(7, D); break;                    /* BIT  7,D         */
-       case 0x7b: BIT(7, E); break;                    /* BIT  7,E         */
-       case 0x7c: BIT(7, H); break;                    /* BIT  7,H         */
-       case 0x7d: BIT(7, L); break;                    /* BIT  7,L         */
-       case 0x7e: BIT_HL(7, RM8(HL)); break;           /* BIT  7,(HL)      */
-       case 0x7f: BIT(7, A); break;                    /* BIT  7,A         */
-       case 0x80: B = RES(0, B); break;                /* RES  0,B         */
-       case 0x81: C = RES(0, C); break;                /* RES  0,C         */
-       case 0x82: D = RES(0, D); break;                /* RES  0,D         */
-       case 0x83: E = RES(0, E); break;                /* RES  0,E         */
-       case 0x84: H = RES(0, H); break;                /* RES  0,H         */
-       case 0x85: L = RES(0, L); break;                /* RES  0,L         */
-       case 0x86: WM8(HL, RES(0, RM8(HL))); break;     /* RES  0,(HL)      */
-       case 0x87: A = RES(0, A); break;                /* RES  0,A         */
-       case 0x88: B = RES(1, B); break;                /* RES  1,B         */
-       case 0x89: C = RES(1, C); break;                /* RES  1,C         */
-       case 0x8a: D = RES(1, D); break;                /* RES  1,D         */
-       case 0x8b: E = RES(1, E); break;                /* RES  1,E         */
-       case 0x8c: H = RES(1, H); break;                /* RES  1,H         */
-       case 0x8d: L = RES(1, L); break;                /* RES  1,L         */
-       case 0x8e: WM8(HL, RES(1, RM8(HL))); break;     /* RES  1,(HL)      */
-       case 0x8f: A = RES(1, A); break;                /* RES  1,A         */
-       case 0x90: B = RES(2, B); break;                /* RES  2,B         */
-       case 0x91: C = RES(2, C); break;                /* RES  2,C         */
-       case 0x92: D = RES(2, D); break;                /* RES  2,D         */
-       case 0x93: E = RES(2, E); break;                /* RES  2,E         */
-       case 0x94: H = RES(2, H); break;                /* RES  2,H         */
-       case 0x95: L = RES(2, L); break;                /* RES  2,L         */
-       case 0x96: WM8(HL, RES(2, RM8(HL))); break;     /* RES  2,(HL)      */
-       case 0x97: A = RES(2, A); break;                /* RES  2,A         */
-       case 0x98: B = RES(3, B); break;                /* RES  3,B         */
-       case 0x99: C = RES(3, C); break;                /* RES  3,C         */
-       case 0x9a: D = RES(3, D); break;                /* RES  3,D         */
-       case 0x9b: E = RES(3, E); break;                /* RES  3,E         */
-       case 0x9c: H = RES(3, H); break;                /* RES  3,H         */
-       case 0x9d: L = RES(3, L); break;                /* RES  3,L         */
-       case 0x9e: WM8(HL, RES(3, RM8(HL))); break;     /* RES  3,(HL)      */
-       case 0x9f: A = RES(3, A); break;                /* RES  3,A         */
-       case 0xa0: B = RES(4,   B); break;              /* RES  4,B         */
-       case 0xa1: C = RES(4,   C); break;              /* RES  4,C         */
-       case 0xa2: D = RES(4,   D); break;              /* RES  4,D         */
-       case 0xa3: E = RES(4,   E); break;              /* RES  4,E         */
-       case 0xa4: H = RES(4,   H); break;              /* RES  4,H         */
-       case 0xa5: L = RES(4,   L); break;              /* RES  4,L         */
-       case 0xa6: WM8(HL, RES(4, RM8(HL))); break;     /* RES  4,(HL)      */
-       case 0xa7: A = RES(4,   A); break;              /* RES  4,A         */
-       case 0xa8: B = RES(5, B); break;                /* RES  5,B         */
-       case 0xa9: C = RES(5, C); break;                /* RES  5,C         */
-       case 0xaa: D = RES(5, D); break;                /* RES  5,D         */
-       case 0xab: E = RES(5, E); break;                /* RES  5,E         */
-       case 0xac: H = RES(5, H); break;                /* RES  5,H         */
-       case 0xad: L = RES(5, L); break;                /* RES  5,L         */
-       case 0xae: WM8(HL, RES(5, RM8(HL))); break;     /* RES  5,(HL)      */
-       case 0xaf: A = RES(5, A); break;                /* RES  5,A         */
-       case 0xb0: B = RES(6, B); break;                /* RES  6,B         */
-       case 0xb1: C = RES(6, C); break;                /* RES  6,C         */
-       case 0xb2: D = RES(6, D); break;                /* RES  6,D         */
-       case 0xb3: E = RES(6, E); break;                /* RES  6,E         */
-       case 0xb4: H = RES(6, H); break;                /* RES  6,H         */
-       case 0xb5: L = RES(6, L); break;                /* RES  6,L         */
-       case 0xb6: WM8(HL, RES(6, RM8(HL))); break;     /* RES  6,(HL)      */
-       case 0xb7: A = RES(6, A); break;                /* RES  6,A         */
-       case 0xb8: B = RES(7, B); break;                /* RES  7,B         */
-       case 0xb9: C = RES(7, C); break;                /* RES  7,C         */
-       case 0xba: D = RES(7, D); break;                /* RES  7,D         */
-       case 0xbb: E = RES(7, E); break;                /* RES  7,E         */
-       case 0xbc: H = RES(7, H); break;                /* RES  7,H         */
-       case 0xbd: L = RES(7, L); break;                /* RES  7,L         */
-       case 0xbe: WM8(HL, RES(7, RM8(HL))); break;     /* RES  7,(HL)      */
-       case 0xbf: A = RES(7, A); break;                /* RES  7,A         */
-       case 0xc0: B = SET(0, B); break;                /* SET  0,B         */
-       case 0xc1: C = SET(0, C); break;                /* SET  0,C         */
-       case 0xc2: D = SET(0, D); break;                /* SET  0,D         */
-       case 0xc3: E = SET(0, E); break;                /* SET  0,E         */
-       case 0xc4: H = SET(0, H); break;                /* SET  0,H         */
-       case 0xc5: L = SET(0, L); break;                /* SET  0,L         */
-       case 0xc6: WM8(HL, SET(0, RM8(HL))); break;     /* SET  0,(HL)      */
-       case 0xc7: A = SET(0, A); break;                /* SET  0,A         */
-       case 0xc8: B = SET(1, B); break;                /* SET  1,B         */
-       case 0xc9: C = SET(1, C); break;                /* SET  1,C         */
-       case 0xca: D = SET(1, D); break;                /* SET  1,D         */
-       case 0xcb: E = SET(1, E); break;                /* SET  1,E         */
-       case 0xcc: H = SET(1, H); break;                /* SET  1,H         */
-       case 0xcd: L = SET(1, L); break;                /* SET  1,L         */
-       case 0xce: WM8(HL, SET(1, RM8(HL))); break;     /* SET  1,(HL)      */
-       case 0xcf: A = SET(1, A); break;                /* SET  1,A         */
-       case 0xd0: B = SET(2, B); break;                /* SET  2,B         */
-       case 0xd1: C = SET(2, C); break;                /* SET  2,C         */
-       case 0xd2: D = SET(2, D); break;                /* SET  2,D         */
-       case 0xd3: E = SET(2, E); break;                /* SET  2,E         */
-       case 0xd4: H = SET(2, H); break;                /* SET  2,H         */
-       case 0xd5: L = SET(2, L); break;                /* SET  2,L         */
-       case 0xd6: WM8(HL, SET(2, RM8(HL))); break;     /* SET  2,(HL)      */
-       case 0xd7: A = SET(2, A); break;                /* SET  2,A         */
-       case 0xd8: B = SET(3, B); break;                /* SET  3,B         */
-       case 0xd9: C = SET(3, C); break;                /* SET  3,C         */
-       case 0xda: D = SET(3, D); break;                /* SET  3,D         */
-       case 0xdb: E = SET(3, E); break;                /* SET  3,E         */
-       case 0xdc: H = SET(3, H); break;                /* SET  3,H         */
-       case 0xdd: L = SET(3, L); break;                /* SET  3,L         */
-       case 0xde: WM8(HL, SET(3, RM8(HL))); break;     /* SET  3,(HL)      */
-       case 0xdf: A = SET(3, A); break;                /* SET  3,A         */
-       case 0xe0: B = SET(4, B); break;                /* SET  4,B         */
-       case 0xe1: C = SET(4, C); break;                /* SET  4,C         */
-       case 0xe2: D = SET(4, D); break;                /* SET  4,D         */
-       case 0xe3: E = SET(4, E); break;                /* SET  4,E         */
-       case 0xe4: H = SET(4, H); break;                /* SET  4,H         */
-       case 0xe5: L = SET(4, L); break;                /* SET  4,L         */
-       case 0xe6: WM8(HL, SET(4, RM8(HL))); break;     /* SET  4,(HL)      */
-       case 0xe7: A = SET(4, A); break;                /* SET  4,A         */
-       case 0xe8: B = SET(5, B); break;                /* SET  5,B         */
-       case 0xe9: C = SET(5, C); break;                /* SET  5,C         */
-       case 0xea: D = SET(5, D); break;                /* SET  5,D         */
-       case 0xeb: E = SET(5, E); break;                /* SET  5,E         */
-       case 0xec: H = SET(5, H); break;                /* SET  5,H         */
-       case 0xed: L = SET(5, L); break;                /* SET  5,L         */
-       case 0xee: WM8(HL, SET(5, RM8(HL))); break;     /* SET  5,(HL)      */
-       case 0xef: A = SET(5, A); break;                /* SET  5,A         */
-       case 0xf0: B = SET(6, B); break;                /* SET  6,B         */
-       case 0xf1: C = SET(6, C); break;                /* SET  6,C         */
-       case 0xf2: D = SET(6, D); break;                /* SET  6,D         */
-       case 0xf3: E = SET(6, E); break;                /* SET  6,E         */
-       case 0xf4: H = SET(6, H); break;                /* SET  6,H         */
-       case 0xf5: L = SET(6, L); break;                /* SET  6,L         */
-       case 0xf6: WM8(HL, SET(6, RM8(HL))); break;     /* SET  6,(HL)      */
-       case 0xf7: A = SET(6, A); break;                /* SET  6,A         */
-       case 0xf8: B = SET(7, B); break;                /* SET  7,B         */
-       case 0xf9: C = SET(7, C); break;                /* SET  7,C         */
-       case 0xfa: D = SET(7, D); break;                /* SET  7,D         */
-       case 0xfb: E = SET(7, E); break;                /* SET  7,E         */
-       case 0xfc: H = SET(7, H); break;                /* SET  7,H         */
-       case 0xfd: L = SET(7, L); break;                /* SET  7,L         */
-       case 0xfe: WM8(HL, SET(7, RM8(HL))); break;     /* SET  7,(HL)      */
-       case 0xff: A = SET(7, A); break;                /* SET  7,A         */
+       case 0x00: B = RLC(B); break;                                           /* RLC  B           */
+       case 0x01: C = RLC(C); break;                                           /* RLC  C           */
+       case 0x02: D = RLC(D); break;                                           /* RLC  D           */
+       case 0x03: E = RLC(E); break;                                           /* RLC  E           */
+       case 0x04: H = RLC(H); break;                                           /* RLC  H           */
+       case 0x05: L = RLC(L); break;                                           /* RLC  L           */
+       case 0x06: v = RLC(RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;         /* RLC  (HL)        */
+       case 0x07: A = RLC(A); break;                                           /* RLC  A           */
+       case 0x08: B = RRC(B); break;                                           /* RRC  B           */
+       case 0x09: C = RRC(C); break;                                           /* RRC  C           */
+       case 0x0a: D = RRC(D); break;                                           /* RRC  D           */
+       case 0x0b: E = RRC(E); break;                                           /* RRC  E           */
+       case 0x0c: H = RRC(H); break;                                           /* RRC  H           */
+       case 0x0d: L = RRC(L); break;                                           /* RRC  L           */
+       case 0x0e: v = RRC(RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;         /* RRC  (HL)        */
+       case 0x0f: A = RRC(A); break;                                           /* RRC  A           */
+       case 0x10: B = RL(B); break;                                            /* RL   B           */
+       case 0x11: C = RL(C); break;                                            /* RL   C           */
+       case 0x12: D = RL(D); break;                                            /* RL   D           */
+       case 0x13: E = RL(E); break;                                            /* RL   E           */
+       case 0x14: H = RL(H); break;                                            /* RL   H           */
+       case 0x15: L = RL(L); break;                                            /* RL   L           */
+       case 0x16: v = RL(RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;          /* RL   (HL)        */
+       case 0x17: A = RL(A); break;                                            /* RL   A           */
+       case 0x18: B = RR(B); break;                                            /* RR   B           */
+       case 0x19: C = RR(C); break;                                            /* RR   C           */
+       case 0x1a: D = RR(D); break;                                            /* RR   D           */
+       case 0x1b: E = RR(E); break;                                            /* RR   E           */
+       case 0x1c: H = RR(H); break;                                            /* RR   H           */
+       case 0x1d: L = RR(L); break;                                            /* RR   L           */
+       case 0x1e: v = RR(RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;          /* RR   (HL)        */
+       case 0x1f: A = RR(A); break;                                            /* RR   A           */
+       case 0x20: B = SLA(B); break;                                           /* SLA  B           */
+       case 0x21: C = SLA(C); break;                                           /* SLA  C           */
+       case 0x22: D = SLA(D); break;                                           /* SLA  D           */
+       case 0x23: E = SLA(E); break;                                           /* SLA  E           */
+       case 0x24: H = SLA(H); break;                                           /* SLA  H           */
+       case 0x25: L = SLA(L); break;                                           /* SLA  L           */
+       case 0x26: v = SLA(RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;         /* SLA  (HL)        */
+       case 0x27: A = SLA(A); break;                                           /* SLA  A           */
+       case 0x28: B = SRA(B); break;                                           /* SRA  B           */
+       case 0x29: C = SRA(C); break;                                           /* SRA  C           */
+       case 0x2a: D = SRA(D); break;                                           /* SRA  D           */
+       case 0x2b: E = SRA(E); break;                                           /* SRA  E           */
+       case 0x2c: H = SRA(H); break;                                           /* SRA  H           */
+       case 0x2d: L = SRA(L); break;                                           /* SRA  L           */
+       case 0x2e: v = SRA(RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;         /* SRA  (HL)        */
+       case 0x2f: A = SRA(A); break;                                           /* SRA  A           */
+       case 0x30: B = SLL(B); break;                                           /* SLL  B           */
+       case 0x31: C = SLL(C); break;                                           /* SLL  C           */
+       case 0x32: D = SLL(D); break;                                           /* SLL  D           */
+       case 0x33: E = SLL(E); break;                                           /* SLL  E           */
+       case 0x34: H = SLL(H); break;                                           /* SLL  H           */
+       case 0x35: L = SLL(L); break;                                           /* SLL  L           */
+       case 0x36: v = SLL(RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;         /* SLL  (HL)        */
+       case 0x37: A = SLL(A); break;                                           /* SLL  A           */
+       case 0x38: B = SRL(B); break;                                           /* SRL  B           */
+       case 0x39: C = SRL(C); break;                                           /* SRL  C           */
+       case 0x3a: D = SRL(D); break;                                           /* SRL  D           */
+       case 0x3b: E = SRL(E); break;                                           /* SRL  E           */
+       case 0x3c: H = SRL(H); break;                                           /* SRL  H           */
+       case 0x3d: L = SRL(L); break;                                           /* SRL  L           */
+       case 0x3e: v = SRL(RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;         /* SRL  (HL)        */
+       case 0x3f: A = SRL(A); break;                                           /* SRL  A           */
+       case 0x40: BIT(0, B); break;                                            /* BIT  0,B         */
+       case 0x41: BIT(0, C); break;                                            /* BIT  0,C         */
+       case 0x42: BIT(0, D); break;                                            /* BIT  0,D         */
+       case 0x43: BIT(0, E); break;                                            /* BIT  0,E         */
+       case 0x44: BIT(0, H); break;                                            /* BIT  0,H         */
+       case 0x45: BIT(0, L); break;                                            /* BIT  0,L         */
+       case 0x46: v = RM8(HL); CLOCK_IN_OP(1); BIT_HL(0, v); break;            /* BIT  0,(HL)      */
+       case 0x47: BIT(0, A); break;                                            /* BIT  0,A         */
+       case 0x48: BIT(1, B); break;                                            /* BIT  1,B         */
+       case 0x49: BIT(1, C); break;                                            /* BIT  1,C         */
+       case 0x4a: BIT(1, D); break;                                            /* BIT  1,D         */
+       case 0x4b: BIT(1, E); break;                                            /* BIT  1,E         */
+       case 0x4c: BIT(1, H); break;                                            /* BIT  1,H         */
+       case 0x4d: BIT(1, L); break;                                            /* BIT  1,L         */
+       case 0x4e: v = RM8(HL); CLOCK_IN_OP(1); BIT_HL(1, v); break;            /* BIT  1,(HL)      */
+       case 0x4f: BIT(1, A); break;                                            /* BIT  1,A         */
+       case 0x50: BIT(2, B); break;                                            /* BIT  2,B         */
+       case 0x51: BIT(2, C); break;                                            /* BIT  2,C         */
+       case 0x52: BIT(2, D); break;                                            /* BIT  2,D         */
+       case 0x53: BIT(2, E); break;                                            /* BIT  2,E         */
+       case 0x54: BIT(2, H); break;                                            /* BIT  2,H         */
+       case 0x55: BIT(2, L); break;                                            /* BIT  2,L         */
+       case 0x56: v = RM8(HL); CLOCK_IN_OP(1); BIT_HL(2, v); break;            /* BIT  2,(HL)      */
+       case 0x57: BIT(2, A); break;                                            /* BIT  2,A         */
+       case 0x58: BIT(3, B); break;                                            /* BIT  3,B         */
+       case 0x59: BIT(3, C); break;                                            /* BIT  3,C         */
+       case 0x5a: BIT(3, D); break;                                            /* BIT  3,D         */
+       case 0x5b: BIT(3, E); break;                                            /* BIT  3,E         */
+       case 0x5c: BIT(3, H); break;                                            /* BIT  3,H         */
+       case 0x5d: BIT(3, L); break;                                            /* BIT  3,L         */
+       case 0x5e: v = RM8(HL); CLOCK_IN_OP(1); BIT_HL(3, v); break;            /* BIT  3,(HL)      */
+       case 0x5f: BIT(3, A); break;                                            /* BIT  3,A         */
+       case 0x60: BIT(4, B); break;                                            /* BIT  4,B         */
+       case 0x61: BIT(4, C); break;                                            /* BIT  4,C         */
+       case 0x62: BIT(4, D); break;                                            /* BIT  4,D         */
+       case 0x63: BIT(4, E); break;                                            /* BIT  4,E         */
+       case 0x64: BIT(4, H); break;                                            /* BIT  4,H         */
+       case 0x65: BIT(4, L); break;                                            /* BIT  4,L         */
+       case 0x66: v = RM8(HL); CLOCK_IN_OP(1); BIT_HL(4, v); break;            /* BIT  4,(HL)      */
+       case 0x67: BIT(4, A); break;                                            /* BIT  4,A         */
+       case 0x68: BIT(5, B); break;                                            /* BIT  5,B         */
+       case 0x69: BIT(5, C); break;                                            /* BIT  5,C         */
+       case 0x6a: BIT(5, D); break;                                            /* BIT  5,D         */
+       case 0x6b: BIT(5, E); break;                                            /* BIT  5,E         */
+       case 0x6c: BIT(5, H); break;                                            /* BIT  5,H         */
+       case 0x6d: BIT(5, L); break;                                            /* BIT  5,L         */
+       case 0x6e: v = RM8(HL); CLOCK_IN_OP(1); BIT_HL(5, v); break;            /* BIT  5,(HL)      */
+       case 0x6f: BIT(5, A); break;                                            /* BIT  5,A         */
+       case 0x70: BIT(6, B); break;                                            /* BIT  6,B         */
+       case 0x71: BIT(6, C); break;                                            /* BIT  6,C         */
+       case 0x72: BIT(6, D); break;                                            /* BIT  6,D         */
+       case 0x73: BIT(6, E); break;                                            /* BIT  6,E         */
+       case 0x74: BIT(6, H); break;                                            /* BIT  6,H         */
+       case 0x75: BIT(6, L); break;                                            /* BIT  6,L         */
+       case 0x76: v = RM8(HL); CLOCK_IN_OP(1); BIT_HL(6, v); break;            /* BIT  6,(HL)      */
+       case 0x77: BIT(6, A); break;                                            /* BIT  6,A         */
+       case 0x78: BIT(7, B); break;                                            /* BIT  7,B         */
+       case 0x79: BIT(7, C); break;                                            /* BIT  7,C         */
+       case 0x7a: BIT(7, D); break;                                            /* BIT  7,D         */
+       case 0x7b: BIT(7, E); break;                                            /* BIT  7,E         */
+       case 0x7c: BIT(7, H); break;                                            /* BIT  7,H         */
+       case 0x7d: BIT(7, L); break;                                            /* BIT  7,L         */
+       case 0x7e: v = RM8(HL); CLOCK_IN_OP(1); BIT_HL(7, v); break;            /* BIT  7,(HL)      */
+       case 0x7f: BIT(7, A); break;                                            /* BIT  7,A         */
+       case 0x80: B = RES(0, B); break;                                        /* RES  0,B         */
+       case 0x81: C = RES(0, C); break;                                        /* RES  0,C         */
+       case 0x82: D = RES(0, D); break;                                        /* RES  0,D         */
+       case 0x83: E = RES(0, E); break;                                        /* RES  0,E         */
+       case 0x84: H = RES(0, H); break;                                        /* RES  0,H         */
+       case 0x85: L = RES(0, L); break;                                        /* RES  0,L         */
+       case 0x86: v = RES(0, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* RES  0,(HL)      */
+       case 0x87: A = RES(0, A); break;                                        /* RES  0,A         */
+       case 0x88: B = RES(1, B); break;                                        /* RES  1,B         */
+       case 0x89: C = RES(1, C); break;                                        /* RES  1,C         */
+       case 0x8a: D = RES(1, D); break;                                        /* RES  1,D         */
+       case 0x8b: E = RES(1, E); break;                                        /* RES  1,E         */
+       case 0x8c: H = RES(1, H); break;                                        /* RES  1,H         */
+       case 0x8d: L = RES(1, L); break;                                        /* RES  1,L         */
+       case 0x8e: v = RES(1, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* RES  1,(HL)      */
+       case 0x8f: A = RES(1, A); break;                                        /* RES  1,A         */
+       case 0x90: B = RES(2, B); break;                                        /* RES  2,B         */
+       case 0x91: C = RES(2, C); break;                                        /* RES  2,C         */
+       case 0x92: D = RES(2, D); break;                                        /* RES  2,D         */
+       case 0x93: E = RES(2, E); break;                                        /* RES  2,E         */
+       case 0x94: H = RES(2, H); break;                                        /* RES  2,H         */
+       case 0x95: L = RES(2, L); break;                                        /* RES  2,L         */
+       case 0x96: v = RES(2, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* RES  2,(HL)      */
+       case 0x97: A = RES(2, A); break;                                        /* RES  2,A         */
+       case 0x98: B = RES(3, B); break;                                        /* RES  3,B         */
+       case 0x99: C = RES(3, C); break;                                        /* RES  3,C         */
+       case 0x9a: D = RES(3, D); break;                                        /* RES  3,D         */
+       case 0x9b: E = RES(3, E); break;                                        /* RES  3,E         */
+       case 0x9c: H = RES(3, H); break;                                        /* RES  3,H         */
+       case 0x9d: L = RES(3, L); break;                                        /* RES  3,L         */
+       case 0x9e: v = RES(3, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* RES  3,(HL)      */
+       case 0x9f: A = RES(3, A); break;                                        /* RES  3,A         */
+       case 0xa0: B = RES(4,   B); break;                                      /* RES  4,B         */
+       case 0xa1: C = RES(4,   C); break;                                      /* RES  4,C         */
+       case 0xa2: D = RES(4,   D); break;                                      /* RES  4,D         */
+       case 0xa3: E = RES(4,   E); break;                                      /* RES  4,E         */
+       case 0xa4: H = RES(4,   H); break;                                      /* RES  4,H         */
+       case 0xa5: L = RES(4,   L); break;                                      /* RES  4,L         */
+       case 0xa6: v = RES(4, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* RES  4,(HL)      */
+       case 0xa7: A = RES(4,   A); break;                                      /* RES  4,A         */
+       case 0xa8: B = RES(5, B); break;                                        /* RES  5,B         */
+       case 0xa9: C = RES(5, C); break;                                        /* RES  5,C         */
+       case 0xaa: D = RES(5, D); break;                                        /* RES  5,D         */
+       case 0xab: E = RES(5, E); break;                                        /* RES  5,E         */
+       case 0xac: H = RES(5, H); break;                                        /* RES  5,H         */
+       case 0xad: L = RES(5, L); break;                                        /* RES  5,L         */
+       case 0xae: v = RES(5, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* RES  5,(HL)      */
+       case 0xaf: A = RES(5, A); break;                                        /* RES  5,A         */
+       case 0xb0: B = RES(6, B); break;                                        /* RES  6,B         */
+       case 0xb1: C = RES(6, C); break;                                        /* RES  6,C         */
+       case 0xb2: D = RES(6, D); break;                                        /* RES  6,D         */
+       case 0xb3: E = RES(6, E); break;                                        /* RES  6,E         */
+       case 0xb4: H = RES(6, H); break;                                        /* RES  6,H         */
+       case 0xb5: L = RES(6, L); break;                                        /* RES  6,L         */
+       case 0xb6: v = RES(6, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* RES  6,(HL)      */
+       case 0xb7: A = RES(6, A); break;                                        /* RES  6,A         */
+       case 0xb8: B = RES(7, B); break;                                        /* RES  7,B         */
+       case 0xb9: C = RES(7, C); break;                                        /* RES  7,C         */
+       case 0xba: D = RES(7, D); break;                                        /* RES  7,D         */
+       case 0xbb: E = RES(7, E); break;                                        /* RES  7,E         */
+       case 0xbc: H = RES(7, H); break;                                        /* RES  7,H         */
+       case 0xbd: L = RES(7, L); break;                                        /* RES  7,L         */
+       case 0xbe: v = RES(7, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* RES  7,(HL)      */
+       case 0xbf: A = RES(7, A); break;                                        /* RES  7,A         */
+       case 0xc0: B = SET(0, B); break;                                        /* SET  0,B         */
+       case 0xc1: C = SET(0, C); break;                                        /* SET  0,C         */
+       case 0xc2: D = SET(0, D); break;                                        /* SET  0,D         */
+       case 0xc3: E = SET(0, E); break;                                        /* SET  0,E         */
+       case 0xc4: H = SET(0, H); break;                                        /* SET  0,H         */
+       case 0xc5: L = SET(0, L); break;                                        /* SET  0,L         */
+       case 0xc6: v = SET(0, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* SET  0,(HL)      */
+       case 0xc7: A = SET(0, A); break;                                        /* SET  0,A         */
+       case 0xc8: B = SET(1, B); break;                                        /* SET  1,B         */
+       case 0xc9: C = SET(1, C); break;                                        /* SET  1,C         */
+       case 0xca: D = SET(1, D); break;                                        /* SET  1,D         */
+       case 0xcb: E = SET(1, E); break;                                        /* SET  1,E         */
+       case 0xcc: H = SET(1, H); break;                                        /* SET  1,H         */
+       case 0xcd: L = SET(1, L); break;                                        /* SET  1,L         */
+       case 0xce: v = SET(1, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* SET  1,(HL)      */
+       case 0xcf: A = SET(1, A); break;                                        /* SET  1,A         */
+       case 0xd0: B = SET(2, B); break;                                        /* SET  2,B         */
+       case 0xd1: C = SET(2, C); break;                                        /* SET  2,C         */
+       case 0xd2: D = SET(2, D); break;                                        /* SET  2,D         */
+       case 0xd3: E = SET(2, E); break;                                        /* SET  2,E         */
+       case 0xd4: H = SET(2, H); break;                                        /* SET  2,H         */
+       case 0xd5: L = SET(2, L); break;                                        /* SET  2,L         */
+       case 0xd6: v = SET(2, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* SET  2,(HL)      */
+       case 0xd7: A = SET(2, A); break;                                        /* SET  2,A         */
+       case 0xd8: B = SET(3, B); break;                                        /* SET  3,B         */
+       case 0xd9: C = SET(3, C); break;                                        /* SET  3,C         */
+       case 0xda: D = SET(3, D); break;                                        /* SET  3,D         */
+       case 0xdb: E = SET(3, E); break;                                        /* SET  3,E         */
+       case 0xdc: H = SET(3, H); break;                                        /* SET  3,H         */
+       case 0xdd: L = SET(3, L); break;                                        /* SET  3,L         */
+       case 0xde: v = SET(3, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* SET  3,(HL)      */
+       case 0xdf: A = SET(3, A); break;                                        /* SET  3,A         */
+       case 0xe0: B = SET(4, B); break;                                        /* SET  4,B         */
+       case 0xe1: C = SET(4, C); break;                                        /* SET  4,C         */
+       case 0xe2: D = SET(4, D); break;                                        /* SET  4,D         */
+       case 0xe3: E = SET(4, E); break;                                        /* SET  4,E         */
+       case 0xe4: H = SET(4, H); break;                                        /* SET  4,H         */
+       case 0xe5: L = SET(4, L); break;                                        /* SET  4,L         */
+       case 0xe6: v = SET(4, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* SET  4,(HL)      */
+       case 0xe7: A = SET(4, A); break;                                        /* SET  4,A         */
+       case 0xe8: B = SET(5, B); break;                                        /* SET  5,B         */
+       case 0xe9: C = SET(5, C); break;                                        /* SET  5,C         */
+       case 0xea: D = SET(5, D); break;                                        /* SET  5,D         */
+       case 0xeb: E = SET(5, E); break;                                        /* SET  5,E         */
+       case 0xec: H = SET(5, H); break;                                        /* SET  5,H         */
+       case 0xed: L = SET(5, L); break;                                        /* SET  5,L         */
+       case 0xee: v = SET(5, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* SET  5,(HL)      */
+       case 0xef: A = SET(5, A); break;                                        /* SET  5,A         */
+       case 0xf0: B = SET(6, B); break;                                        /* SET  6,B         */
+       case 0xf1: C = SET(6, C); break;                                        /* SET  6,C         */
+       case 0xf2: D = SET(6, D); break;                                        /* SET  6,D         */
+       case 0xf3: E = SET(6, E); break;                                        /* SET  6,E         */
+       case 0xf4: H = SET(6, H); break;                                        /* SET  6,H         */
+       case 0xf5: L = SET(6, L); break;                                        /* SET  6,L         */
+       case 0xf6: v = SET(6, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* SET  6,(HL)      */
+       case 0xf7: A = SET(6, A); break;                                        /* SET  6,A         */
+       case 0xf8: B = SET(7, B); break;                                        /* SET  7,B         */
+       case 0xf9: C = SET(7, C); break;                                        /* SET  7,C         */
+       case 0xfa: D = SET(7, D); break;                                        /* SET  7,D         */
+       case 0xfb: E = SET(7, E); break;                                        /* SET  7,E         */
+       case 0xfc: H = SET(7, H); break;                                        /* SET  7,H         */
+       case 0xfd: L = SET(7, L); break;                                        /* SET  7,L         */
+       case 0xfe: v = SET(7, RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;      /* SET  7,(HL)      */
+       case 0xff: A = SET(7, A); break;                                        /* SET  7,A         */
 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
        default: __assume(0);
 #endif
        }
 }
 
+
 void Z80::OP_XY(uint8_t code)
 {
+       // Done: M1 + M1 + R + R + 2
+       uint8_t v;
+
        icount -= cc_xycb[code];
-       
+
        switch(code) {
-       case 0x00: B = RLC(RM8(ea)); WM8(ea, B); break;         /* RLC  B=(XY+o)    */
-       case 0x01: C = RLC(RM8(ea)); WM8(ea, C); break;         /* RLC  C=(XY+o)    */
-       case 0x02: D = RLC(RM8(ea)); WM8(ea, D); break;         /* RLC  D=(XY+o)    */
-       case 0x03: E = RLC(RM8(ea)); WM8(ea, E); break;         /* RLC  E=(XY+o)    */
-       case 0x04: H = RLC(RM8(ea)); WM8(ea, H); break;         /* RLC  H=(XY+o)    */
-       case 0x05: L = RLC(RM8(ea)); WM8(ea, L); break;         /* RLC  L=(XY+o)    */
-       case 0x06: WM8(ea, RLC(RM8(ea))); break;                /* RLC  (XY+o)      */
-       case 0x07: A = RLC(RM8(ea)); WM8(ea, A); break;         /* RLC  A=(XY+o)    */
-       case 0x08: B = RRC(RM8(ea)); WM8(ea, B); break;         /* RRC  B=(XY+o)    */
-       case 0x09: C = RRC(RM8(ea)); WM8(ea, C); break;         /* RRC  C=(XY+o)    */
-       case 0x0a: D = RRC(RM8(ea)); WM8(ea, D); break;         /* RRC  D=(XY+o)    */
-       case 0x0b: E = RRC(RM8(ea)); WM8(ea, E); break;         /* RRC  E=(XY+o)    */
-       case 0x0c: H = RRC(RM8(ea)); WM8(ea, H); break;         /* RRC  H=(XY+o)    */
-       case 0x0d: L = RRC(RM8(ea)); WM8(ea, L); break;         /* RRC  L=(XY+o)    */
-       case 0x0e: WM8(ea, RRC(RM8(ea))); break;                /* RRC  (XY+o)      */
-       case 0x0f: A = RRC(RM8(ea)); WM8(ea, A); break;         /* RRC  A=(XY+o)    */
-       case 0x10: B = RL(RM8(ea)); WM8(ea, B); break;          /* RL   B=(XY+o)    */
-       case 0x11: C = RL(RM8(ea)); WM8(ea, C); break;          /* RL   C=(XY+o)    */
-       case 0x12: D = RL(RM8(ea)); WM8(ea, D); break;          /* RL   D=(XY+o)    */
-       case 0x13: E = RL(RM8(ea)); WM8(ea, E); break;          /* RL   E=(XY+o)    */
-       case 0x14: H = RL(RM8(ea)); WM8(ea, H); break;          /* RL   H=(XY+o)    */
-       case 0x15: L = RL(RM8(ea)); WM8(ea, L); break;          /* RL   L=(XY+o)    */
-       case 0x16: WM8(ea, RL(RM8(ea))); break;                 /* RL   (XY+o)      */
-       case 0x17: A = RL(RM8(ea)); WM8(ea, A); break;          /* RL   A=(XY+o)    */
-       case 0x18: B = RR(RM8(ea)); WM8(ea, B); break;          /* RR   B=(XY+o)    */
-       case 0x19: C = RR(RM8(ea)); WM8(ea, C); break;          /* RR   C=(XY+o)    */
-       case 0x1a: D = RR(RM8(ea)); WM8(ea, D); break;          /* RR   D=(XY+o)    */
-       case 0x1b: E = RR(RM8(ea)); WM8(ea, E); break;          /* RR   E=(XY+o)    */
-       case 0x1c: H = RR(RM8(ea)); WM8(ea, H); break;          /* RR   H=(XY+o)    */
-       case 0x1d: L = RR(RM8(ea)); WM8(ea, L); break;          /* RR   L=(XY+o)    */
-       case 0x1e: WM8(ea, RR(RM8(ea))); break;                 /* RR   (XY+o)      */
-       case 0x1f: A = RR(RM8(ea)); WM8(ea, A); break;          /* RR   A=(XY+o)    */
-       case 0x20: B = SLA(RM8(ea)); WM8(ea, B); break;         /* SLA  B=(XY+o)    */
-       case 0x21: C = SLA(RM8(ea)); WM8(ea, C); break;         /* SLA  C=(XY+o)    */
-       case 0x22: D = SLA(RM8(ea)); WM8(ea, D); break;         /* SLA  D=(XY+o)    */
-       case 0x23: E = SLA(RM8(ea)); WM8(ea, E); break;         /* SLA  E=(XY+o)    */
-       case 0x24: H = SLA(RM8(ea)); WM8(ea, H); break;         /* SLA  H=(XY+o)    */
-       case 0x25: L = SLA(RM8(ea)); WM8(ea, L); break;         /* SLA  L=(XY+o)    */
-       case 0x26: WM8(ea, SLA(RM8(ea))); break;                /* SLA  (XY+o)      */
-       case 0x27: A = SLA(RM8(ea)); WM8(ea, A); break;         /* SLA  A=(XY+o)    */
-       case 0x28: B = SRA(RM8(ea)); WM8(ea, B); break;         /* SRA  B=(XY+o)    */
-       case 0x29: C = SRA(RM8(ea)); WM8(ea, C); break;         /* SRA  C=(XY+o)    */
-       case 0x2a: D = SRA(RM8(ea)); WM8(ea, D); break;         /* SRA  D=(XY+o)    */
-       case 0x2b: E = SRA(RM8(ea)); WM8(ea, E); break;         /* SRA  E=(XY+o)    */
-       case 0x2c: H = SRA(RM8(ea)); WM8(ea, H); break;         /* SRA  H=(XY+o)    */
-       case 0x2d: L = SRA(RM8(ea)); WM8(ea, L); break;         /* SRA  L=(XY+o)    */
-       case 0x2e: WM8(ea, SRA(RM8(ea))); break;                /* SRA  (XY+o)      */
-       case 0x2f: A = SRA(RM8(ea)); WM8(ea, A); break;         /* SRA  A=(XY+o)    */
-       case 0x30: B = SLL(RM8(ea)); WM8(ea, B); break;         /* SLL  B=(XY+o)    */
-       case 0x31: C = SLL(RM8(ea)); WM8(ea, C); break;         /* SLL  C=(XY+o)    */
-       case 0x32: D = SLL(RM8(ea)); WM8(ea, D); break;         /* SLL  D=(XY+o)    */
-       case 0x33: E = SLL(RM8(ea)); WM8(ea, E); break;         /* SLL  E=(XY+o)    */
-       case 0x34: H = SLL(RM8(ea)); WM8(ea, H); break;         /* SLL  H=(XY+o)    */
-       case 0x35: L = SLL(RM8(ea)); WM8(ea, L); break;         /* SLL  L=(XY+o)    */
-       case 0x36: WM8(ea, SLL(RM8(ea))); break;                /* SLL  (XY+o)      */
-       case 0x37: A = SLL(RM8(ea)); WM8(ea, A); break;         /* SLL  A=(XY+o)    */
-       case 0x38: B = SRL(RM8(ea)); WM8(ea, B); break;         /* SRL  B=(XY+o)    */
-       case 0x39: C = SRL(RM8(ea)); WM8(ea, C); break;         /* SRL  C=(XY+o)    */
-       case 0x3a: D = SRL(RM8(ea)); WM8(ea, D); break;         /* SRL  D=(XY+o)    */
-       case 0x3b: E = SRL(RM8(ea)); WM8(ea, E); break;         /* SRL  E=(XY+o)    */
-       case 0x3c: H = SRL(RM8(ea)); WM8(ea, H); break;         /* SRL  H=(XY+o)    */
-       case 0x3d: L = SRL(RM8(ea)); WM8(ea, L); break;         /* SRL  L=(XY+o)    */
-       case 0x3e: WM8(ea, SRL(RM8(ea))); break;                /* SRL  (XY+o)      */
-       case 0x3f: A = SRL(RM8(ea)); WM8(ea, A); break;         /* SRL  A=(XY+o)    */
-       case 0x40: BIT_XY(0, RM8(ea)); break;                   /* BIT  0,(XY+o)    */
-       case 0x41: BIT_XY(0, RM8(ea)); break;                   /* BIT  0,(XY+o)    */
-       case 0x42: BIT_XY(0, RM8(ea)); break;                   /* BIT  0,(XY+o)    */
-       case 0x43: BIT_XY(0, RM8(ea)); break;                   /* BIT  0,(XY+o)    */
-       case 0x44: BIT_XY(0, RM8(ea)); break;                   /* BIT  0,(XY+o)    */
-       case 0x45: BIT_XY(0, RM8(ea)); break;                   /* BIT  0,(XY+o)    */
-       case 0x46: BIT_XY(0, RM8(ea)); break;                   /* BIT  0,(XY+o)    */
-       case 0x47: BIT_XY(0, RM8(ea)); break;                   /* BIT  0,(XY+o)    */
-       case 0x48: BIT_XY(1, RM8(ea)); break;                   /* BIT  1,(XY+o)    */
-       case 0x49: BIT_XY(1, RM8(ea)); break;                   /* BIT  1,(XY+o)    */
-       case 0x4a: BIT_XY(1, RM8(ea)); break;                   /* BIT  1,(XY+o)    */
-       case 0x4b: BIT_XY(1, RM8(ea)); break;                   /* BIT  1,(XY+o)    */
-       case 0x4c: BIT_XY(1, RM8(ea)); break;                   /* BIT  1,(XY+o)    */
-       case 0x4d: BIT_XY(1, RM8(ea)); break;                   /* BIT  1,(XY+o)    */
-       case 0x4e: BIT_XY(1, RM8(ea)); break;                   /* BIT  1,(XY+o)    */
-       case 0x4f: BIT_XY(1, RM8(ea)); break;                   /* BIT  1,(XY+o)    */
-       case 0x50: BIT_XY(2, RM8(ea)); break;                   /* BIT  2,(XY+o)    */
-       case 0x51: BIT_XY(2, RM8(ea)); break;                   /* BIT  2,(XY+o)    */
-       case 0x52: BIT_XY(2, RM8(ea)); break;                   /* BIT  2,(XY+o)    */
-       case 0x53: BIT_XY(2, RM8(ea)); break;                   /* BIT  2,(XY+o)    */
-       case 0x54: BIT_XY(2, RM8(ea)); break;                   /* BIT  2,(XY+o)    */
-       case 0x55: BIT_XY(2, RM8(ea)); break;                   /* BIT  2,(XY+o)    */
-       case 0x56: BIT_XY(2, RM8(ea)); break;                   /* BIT  2,(XY+o)    */
-       case 0x57: BIT_XY(2, RM8(ea)); break;                   /* BIT  2,(XY+o)    */
-       case 0x58: BIT_XY(3, RM8(ea)); break;                   /* BIT  3,(XY+o)    */
-       case 0x59: BIT_XY(3, RM8(ea)); break;                   /* BIT  3,(XY+o)    */
-       case 0x5a: BIT_XY(3, RM8(ea)); break;                   /* BIT  3,(XY+o)    */
-       case 0x5b: BIT_XY(3, RM8(ea)); break;                   /* BIT  3,(XY+o)    */
-       case 0x5c: BIT_XY(3, RM8(ea)); break;                   /* BIT  3,(XY+o)    */
-       case 0x5d: BIT_XY(3, RM8(ea)); break;                   /* BIT  3,(XY+o)    */
-       case 0x5e: BIT_XY(3, RM8(ea)); break;                   /* BIT  3,(XY+o)    */
-       case 0x5f: BIT_XY(3, RM8(ea)); break;                   /* BIT  3,(XY+o)    */
-       case 0x60: BIT_XY(4, RM8(ea)); break;                   /* BIT  4,(XY+o)    */
-       case 0x61: BIT_XY(4, RM8(ea)); break;                   /* BIT  4,(XY+o)    */
-       case 0x62: BIT_XY(4, RM8(ea)); break;                   /* BIT  4,(XY+o)    */
-       case 0x63: BIT_XY(4, RM8(ea)); break;                   /* BIT  4,(XY+o)    */
-       case 0x64: BIT_XY(4, RM8(ea)); break;                   /* BIT  4,(XY+o)    */
-       case 0x65: BIT_XY(4, RM8(ea)); break;                   /* BIT  4,(XY+o)    */
-       case 0x66: BIT_XY(4, RM8(ea)); break;                   /* BIT  4,(XY+o)    */
-       case 0x67: BIT_XY(4, RM8(ea)); break;                   /* BIT  4,(XY+o)    */
-       case 0x68: BIT_XY(5, RM8(ea)); break;                   /* BIT  5,(XY+o)    */
-       case 0x69: BIT_XY(5, RM8(ea)); break;                   /* BIT  5,(XY+o)    */
-       case 0x6a: BIT_XY(5, RM8(ea)); break;                   /* BIT  5,(XY+o)    */
-       case 0x6b: BIT_XY(5, RM8(ea)); break;                   /* BIT  5,(XY+o)    */
-       case 0x6c: BIT_XY(5, RM8(ea)); break;                   /* BIT  5,(XY+o)    */
-       case 0x6d: BIT_XY(5, RM8(ea)); break;                   /* BIT  5,(XY+o)    */
-       case 0x6e: BIT_XY(5, RM8(ea)); break;                   /* BIT  5,(XY+o)    */
-       case 0x6f: BIT_XY(5, RM8(ea)); break;                   /* BIT  5,(XY+o)    */
-       case 0x70: BIT_XY(6, RM8(ea)); break;                   /* BIT  6,(XY+o)    */
-       case 0x71: BIT_XY(6, RM8(ea)); break;                   /* BIT  6,(XY+o)    */
-       case 0x72: BIT_XY(6, RM8(ea)); break;                   /* BIT  6,(XY+o)    */
-       case 0x73: BIT_XY(6, RM8(ea)); break;                   /* BIT  6,(XY+o)    */
-       case 0x74: BIT_XY(6, RM8(ea)); break;                   /* BIT  6,(XY+o)    */
-       case 0x75: BIT_XY(6, RM8(ea)); break;                   /* BIT  6,(XY+o)    */
-       case 0x76: BIT_XY(6, RM8(ea)); break;                   /* BIT  6,(XY+o)    */
-       case 0x77: BIT_XY(6, RM8(ea)); break;                   /* BIT  6,(XY+o)    */
-       case 0x78: BIT_XY(7, RM8(ea)); break;                   /* BIT  7,(XY+o)    */
-       case 0x79: BIT_XY(7, RM8(ea)); break;                   /* BIT  7,(XY+o)    */
-       case 0x7a: BIT_XY(7, RM8(ea)); break;                   /* BIT  7,(XY+o)    */
-       case 0x7b: BIT_XY(7, RM8(ea)); break;                   /* BIT  7,(XY+o)    */
-       case 0x7c: BIT_XY(7, RM8(ea)); break;                   /* BIT  7,(XY+o)    */
-       case 0x7d: BIT_XY(7, RM8(ea)); break;                   /* BIT  7,(XY+o)    */
-       case 0x7e: BIT_XY(7, RM8(ea)); break;                   /* BIT  7,(XY+o)    */
-       case 0x7f: BIT_XY(7, RM8(ea)); break;                   /* BIT  7,(XY+o)    */
-       case 0x80: B = RES(0, RM8(ea)); WM8(ea, B); break;      /* RES  0,B=(XY+o)  */
-       case 0x81: C = RES(0, RM8(ea)); WM8(ea, C); break;      /* RES  0,C=(XY+o)  */
-       case 0x82: D = RES(0, RM8(ea)); WM8(ea, D); break;      /* RES  0,D=(XY+o)  */
-       case 0x83: E = RES(0, RM8(ea)); WM8(ea, E); break;      /* RES  0,E=(XY+o)  */
-       case 0x84: H = RES(0, RM8(ea)); WM8(ea, H); break;      /* RES  0,H=(XY+o)  */
-       case 0x85: L = RES(0, RM8(ea)); WM8(ea, L); break;      /* RES  0,L=(XY+o)  */
-       case 0x86: WM8(ea, RES(0, RM8(ea))); break;             /* RES  0,(XY+o)    */
-       case 0x87: A = RES(0, RM8(ea)); WM8(ea, A); break;      /* RES  0,A=(XY+o)  */
-       case 0x88: B = RES(1, RM8(ea)); WM8(ea, B); break;      /* RES  1,B=(XY+o)  */
-       case 0x89: C = RES(1, RM8(ea)); WM8(ea, C); break;      /* RES  1,C=(XY+o)  */
-       case 0x8a: D = RES(1, RM8(ea)); WM8(ea, D); break;      /* RES  1,D=(XY+o)  */
-       case 0x8b: E = RES(1, RM8(ea)); WM8(ea, E); break;      /* RES  1,E=(XY+o)  */
-       case 0x8c: H = RES(1, RM8(ea)); WM8(ea, H); break;      /* RES  1,H=(XY+o)  */
-       case 0x8d: L = RES(1, RM8(ea)); WM8(ea, L); break;      /* RES  1,L=(XY+o)  */
-       case 0x8e: WM8(ea, RES(1, RM8(ea))); break;             /* RES  1,(XY+o)    */
-       case 0x8f: A = RES(1, RM8(ea)); WM8(ea, A); break;      /* RES  1,A=(XY+o)  */
-       case 0x90: B = RES(2, RM8(ea)); WM8(ea, B); break;      /* RES  2,B=(XY+o)  */
-       case 0x91: C = RES(2, RM8(ea)); WM8(ea, C); break;      /* RES  2,C=(XY+o)  */
-       case 0x92: D = RES(2, RM8(ea)); WM8(ea, D); break;      /* RES  2,D=(XY+o)  */
-       case 0x93: E = RES(2, RM8(ea)); WM8(ea, E); break;      /* RES  2,E=(XY+o)  */
-       case 0x94: H = RES(2, RM8(ea)); WM8(ea, H); break;      /* RES  2,H=(XY+o)  */
-       case 0x95: L = RES(2, RM8(ea)); WM8(ea, L); break;      /* RES  2,L=(XY+o)  */
-       case 0x96: WM8(ea, RES(2, RM8(ea))); break;             /* RES  2,(XY+o)    */
-       case 0x97: A = RES(2, RM8(ea)); WM8(ea, A); break;      /* RES  2,A=(XY+o)  */
-       case 0x98: B = RES(3, RM8(ea)); WM8(ea, B); break;      /* RES  3,B=(XY+o)  */
-       case 0x99: C = RES(3, RM8(ea)); WM8(ea, C); break;      /* RES  3,C=(XY+o)  */
-       case 0x9a: D = RES(3, RM8(ea)); WM8(ea, D); break;      /* RES  3,D=(XY+o)  */
-       case 0x9b: E = RES(3, RM8(ea)); WM8(ea, E); break;      /* RES  3,E=(XY+o)  */
-       case 0x9c: H = RES(3, RM8(ea)); WM8(ea, H); break;      /* RES  3,H=(XY+o)  */
-       case 0x9d: L = RES(3, RM8(ea)); WM8(ea, L); break;      /* RES  3,L=(XY+o)  */
-       case 0x9e: WM8(ea, RES(3, RM8(ea))); break;             /* RES  3,(XY+o)    */
-       case 0x9f: A = RES(3, RM8(ea)); WM8(ea, A); break;      /* RES  3,A=(XY+o)  */
-       case 0xa0: B = RES(4, RM8(ea)); WM8(ea, B); break;      /* RES  4,B=(XY+o)  */
-       case 0xa1: C = RES(4, RM8(ea)); WM8(ea, C); break;      /* RES  4,C=(XY+o)  */
-       case 0xa2: D = RES(4, RM8(ea)); WM8(ea, D); break;      /* RES  4,D=(XY+o)  */
-       case 0xa3: E = RES(4, RM8(ea)); WM8(ea, E); break;      /* RES  4,E=(XY+o)  */
-       case 0xa4: H = RES(4, RM8(ea)); WM8(ea, H); break;      /* RES  4,H=(XY+o)  */
-       case 0xa5: L = RES(4, RM8(ea)); WM8(ea, L); break;      /* RES  4,L=(XY+o)  */
-       case 0xa6: WM8(ea, RES(4, RM8(ea))); break;             /* RES  4,(XY+o)    */
-       case 0xa7: A = RES(4, RM8(ea)); WM8(ea, A); break;      /* RES  4,A=(XY+o)  */
-       case 0xa8: B = RES(5, RM8(ea)); WM8(ea, B); break;      /* RES  5,B=(XY+o)  */
-       case 0xa9: C = RES(5, RM8(ea)); WM8(ea, C); break;      /* RES  5,C=(XY+o)  */
-       case 0xaa: D = RES(5, RM8(ea)); WM8(ea, D); break;      /* RES  5,D=(XY+o)  */
-       case 0xab: E = RES(5, RM8(ea)); WM8(ea, E); break;      /* RES  5,E=(XY+o)  */
-       case 0xac: H = RES(5, RM8(ea)); WM8(ea, H); break;      /* RES  5,H=(XY+o)  */
-       case 0xad: L = RES(5, RM8(ea)); WM8(ea, L); break;      /* RES  5,L=(XY+o)  */
-       case 0xae: WM8(ea, RES(5, RM8(ea))); break;             /* RES  5,(XY+o)    */
-       case 0xaf: A = RES(5, RM8(ea)); WM8(ea, A); break;      /* RES  5,A=(XY+o)  */
-       case 0xb0: B = RES(6, RM8(ea)); WM8(ea, B); break;      /* RES  6,B=(XY+o)  */
-       case 0xb1: C = RES(6, RM8(ea)); WM8(ea, C); break;      /* RES  6,C=(XY+o)  */
-       case 0xb2: D = RES(6, RM8(ea)); WM8(ea, D); break;      /* RES  6,D=(XY+o)  */
-       case 0xb3: E = RES(6, RM8(ea)); WM8(ea, E); break;      /* RES  6,E=(XY+o)  */
-       case 0xb4: H = RES(6, RM8(ea)); WM8(ea, H); break;      /* RES  6,H=(XY+o)  */
-       case 0xb5: L = RES(6, RM8(ea)); WM8(ea, L); break;      /* RES  6,L=(XY+o)  */
-       case 0xb6: WM8(ea, RES(6, RM8(ea))); break;             /* RES  6,(XY+o)    */
-       case 0xb7: A = RES(6, RM8(ea)); WM8(ea, A); break;      /* RES  6,A=(XY+o)  */
-       case 0xb8: B = RES(7, RM8(ea)); WM8(ea, B); break;      /* RES  7,B=(XY+o)  */
-       case 0xb9: C = RES(7, RM8(ea)); WM8(ea, C); break;      /* RES  7,C=(XY+o)  */
-       case 0xba: D = RES(7, RM8(ea)); WM8(ea, D); break;      /* RES  7,D=(XY+o)  */
-       case 0xbb: E = RES(7, RM8(ea)); WM8(ea, E); break;      /* RES  7,E=(XY+o)  */
-       case 0xbc: H = RES(7, RM8(ea)); WM8(ea, H); break;      /* RES  7,H=(XY+o)  */
-       case 0xbd: L = RES(7, RM8(ea)); WM8(ea, L); break;      /* RES  7,L=(XY+o)  */
-       case 0xbe: WM8(ea, RES(7, RM8(ea))); break;             /* RES  7,(XY+o)    */
-       case 0xbf: A = RES(7, RM8(ea)); WM8(ea, A); break;      /* RES  7,A=(XY+o)  */
-       case 0xc0: B = SET(0, RM8(ea)); WM8(ea, B); break;      /* SET  0,B=(XY+o)  */
-       case 0xc1: C = SET(0, RM8(ea)); WM8(ea, C); break;      /* SET  0,C=(XY+o)  */
-       case 0xc2: D = SET(0, RM8(ea)); WM8(ea, D); break;      /* SET  0,D=(XY+o)  */
-       case 0xc3: E = SET(0, RM8(ea)); WM8(ea, E); break;      /* SET  0,E=(XY+o)  */
-       case 0xc4: H = SET(0, RM8(ea)); WM8(ea, H); break;      /* SET  0,H=(XY+o)  */
-       case 0xc5: L = SET(0, RM8(ea)); WM8(ea, L); break;      /* SET  0,L=(XY+o)  */
-       case 0xc6: WM8(ea, SET(0, RM8(ea))); break;             /* SET  0,(XY+o)    */
-       case 0xc7: A = SET(0, RM8(ea)); WM8(ea, A); break;      /* SET  0,A=(XY+o)  */
-       case 0xc8: B = SET(1, RM8(ea)); WM8(ea, B); break;      /* SET  1,B=(XY+o)  */
-       case 0xc9: C = SET(1, RM8(ea)); WM8(ea, C); break;      /* SET  1,C=(XY+o)  */
-       case 0xca: D = SET(1, RM8(ea)); WM8(ea, D); break;      /* SET  1,D=(XY+o)  */
-       case 0xcb: E = SET(1, RM8(ea)); WM8(ea, E); break;      /* SET  1,E=(XY+o)  */
-       case 0xcc: H = SET(1, RM8(ea)); WM8(ea, H); break;      /* SET  1,H=(XY+o)  */
-       case 0xcd: L = SET(1, RM8(ea)); WM8(ea, L); break;      /* SET  1,L=(XY+o)  */
-       case 0xce: WM8(ea, SET(1, RM8(ea))); break;             /* SET  1,(XY+o)    */
-       case 0xcf: A = SET(1, RM8(ea)); WM8(ea, A); break;      /* SET  1,A=(XY+o)  */
-       case 0xd0: B = SET(2, RM8(ea)); WM8(ea, B); break;      /* SET  2,B=(XY+o)  */
-       case 0xd1: C = SET(2, RM8(ea)); WM8(ea, C); break;      /* SET  2,C=(XY+o)  */
-       case 0xd2: D = SET(2, RM8(ea)); WM8(ea, D); break;      /* SET  2,D=(XY+o)  */
-       case 0xd3: E = SET(2, RM8(ea)); WM8(ea, E); break;      /* SET  2,E=(XY+o)  */
-       case 0xd4: H = SET(2, RM8(ea)); WM8(ea, H); break;      /* SET  2,H=(XY+o)  */
-       case 0xd5: L = SET(2, RM8(ea)); WM8(ea, L); break;      /* SET  2,L=(XY+o)  */
-       case 0xd6: WM8(ea, SET(2, RM8(ea))); break;             /* SET  2,(XY+o)    */
-       case 0xd7: A = SET(2, RM8(ea)); WM8(ea, A); break;      /* SET  2,A=(XY+o)  */
-       case 0xd8: B = SET(3, RM8(ea)); WM8(ea, B); break;      /* SET  3,B=(XY+o)  */
-       case 0xd9: C = SET(3, RM8(ea)); WM8(ea, C); break;      /* SET  3,C=(XY+o)  */
-       case 0xda: D = SET(3, RM8(ea)); WM8(ea, D); break;      /* SET  3,D=(XY+o)  */
-       case 0xdb: E = SET(3, RM8(ea)); WM8(ea, E); break;      /* SET  3,E=(XY+o)  */
-       case 0xdc: H = SET(3, RM8(ea)); WM8(ea, H); break;      /* SET  3,H=(XY+o)  */
-       case 0xdd: L = SET(3, RM8(ea)); WM8(ea, L); break;      /* SET  3,L=(XY+o)  */
-       case 0xde: WM8(ea, SET(3, RM8(ea))); break;             /* SET  3,(XY+o)    */
-       case 0xdf: A = SET(3, RM8(ea)); WM8(ea, A); break;      /* SET  3,A=(XY+o)  */
-       case 0xe0: B = SET(4, RM8(ea)); WM8(ea, B); break;      /* SET  4,B=(XY+o)  */
-       case 0xe1: C = SET(4, RM8(ea)); WM8(ea, C); break;      /* SET  4,C=(XY+o)  */
-       case 0xe2: D = SET(4, RM8(ea)); WM8(ea, D); break;      /* SET  4,D=(XY+o)  */
-       case 0xe3: E = SET(4, RM8(ea)); WM8(ea, E); break;      /* SET  4,E=(XY+o)  */
-       case 0xe4: H = SET(4, RM8(ea)); WM8(ea, H); break;      /* SET  4,H=(XY+o)  */
-       case 0xe5: L = SET(4, RM8(ea)); WM8(ea, L); break;      /* SET  4,L=(XY+o)  */
-       case 0xe6: WM8(ea, SET(4, RM8(ea))); break;             /* SET  4,(XY+o)    */
-       case 0xe7: A = SET(4, RM8(ea)); WM8(ea, A); break;      /* SET  4,A=(XY+o)  */
-       case 0xe8: B = SET(5, RM8(ea)); WM8(ea, B); break;      /* SET  5,B=(XY+o)  */
-       case 0xe9: C = SET(5, RM8(ea)); WM8(ea, C); break;      /* SET  5,C=(XY+o)  */
-       case 0xea: D = SET(5, RM8(ea)); WM8(ea, D); break;      /* SET  5,D=(XY+o)  */
-       case 0xeb: E = SET(5, RM8(ea)); WM8(ea, E); break;      /* SET  5,E=(XY+o)  */
-       case 0xec: H = SET(5, RM8(ea)); WM8(ea, H); break;      /* SET  5,H=(XY+o)  */
-       case 0xed: L = SET(5, RM8(ea)); WM8(ea, L); break;      /* SET  5,L=(XY+o)  */
-       case 0xee: WM8(ea, SET(5, RM8(ea))); break;             /* SET  5,(XY+o)    */
-       case 0xef: A = SET(5, RM8(ea)); WM8(ea, A); break;      /* SET  5,A=(XY+o)  */
-       case 0xf0: B = SET(6, RM8(ea)); WM8(ea, B); break;      /* SET  6,B=(XY+o)  */
-       case 0xf1: C = SET(6, RM8(ea)); WM8(ea, C); break;      /* SET  6,C=(XY+o)  */
-       case 0xf2: D = SET(6, RM8(ea)); WM8(ea, D); break;      /* SET  6,D=(XY+o)  */
-       case 0xf3: E = SET(6, RM8(ea)); WM8(ea, E); break;      /* SET  6,E=(XY+o)  */
-       case 0xf4: H = SET(6, RM8(ea)); WM8(ea, H); break;      /* SET  6,H=(XY+o)  */
-       case 0xf5: L = SET(6, RM8(ea)); WM8(ea, L); break;      /* SET  6,L=(XY+o)  */
-       case 0xf6: WM8(ea, SET(6, RM8(ea))); break;             /* SET  6,(XY+o)    */
-       case 0xf7: A = SET(6, RM8(ea)); WM8(ea, A); break;      /* SET  6,A=(XY+o)  */
-       case 0xf8: B = SET(7, RM8(ea)); WM8(ea, B); break;      /* SET  7,B=(XY+o)  */
-       case 0xf9: C = SET(7, RM8(ea)); WM8(ea, C); break;      /* SET  7,C=(XY+o)  */
-       case 0xfa: D = SET(7, RM8(ea)); WM8(ea, D); break;      /* SET  7,D=(XY+o)  */
-       case 0xfb: E = SET(7, RM8(ea)); WM8(ea, E); break;      /* SET  7,E=(XY+o)  */
-       case 0xfc: H = SET(7, RM8(ea)); WM8(ea, H); break;      /* SET  7,H=(XY+o)  */
-       case 0xfd: L = SET(7, RM8(ea)); WM8(ea, L); break;      /* SET  7,L=(XY+o)  */
-       case 0xfe: WM8(ea, SET(7, RM8(ea))); break;             /* SET  7,(XY+o)    */
-       case 0xff: A = SET(7, RM8(ea)); WM8(ea, A); break;      /* SET  7,A=(XY+o)  */
+       case 0x00: B = RLC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;         /* RLC  B=(XY+o)    */
+       case 0x01: C = RLC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;         /* RLC  C=(XY+o)    */
+       case 0x02: D = RLC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;         /* RLC  D=(XY+o)    */
+       case 0x03: E = RLC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;         /* RLC  E=(XY+o)    */
+       case 0x04: H = RLC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;         /* RLC  H=(XY+o)    */
+       case 0x05: L = RLC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;         /* RLC  L=(XY+o)    */
+       case 0x06: v = RLC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;         /* RLC  (XY+o)      */
+       case 0x07: A = RLC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;         /* RLC  A=(XY+o)    */
+       case 0x08: B = RRC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;         /* RRC  B=(XY+o)    */
+       case 0x09: C = RRC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;         /* RRC  C=(XY+o)    */
+       case 0x0a: D = RRC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;         /* RRC  D=(XY+o)    */
+       case 0x0b: E = RRC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;         /* RRC  E=(XY+o)    */
+       case 0x0c: H = RRC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;         /* RRC  H=(XY+o)    */
+       case 0x0d: L = RRC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;         /* RRC  L=(XY+o)    */
+       case 0x0e: v = RRC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;         /* RRC  (XY+o)      */
+       case 0x0f: A = RRC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;         /* RRC  A=(XY+o)    */
+       case 0x10: B = RL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;          /* RL   B=(XY+o)    */
+       case 0x11: C = RL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;          /* RL   C=(XY+o)    */
+       case 0x12: D = RL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;          /* RL   D=(XY+o)    */
+       case 0x13: E = RL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;          /* RL   E=(XY+o)    */
+       case 0x14: H = RL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;          /* RL   H=(XY+o)    */
+       case 0x15: L = RL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;          /* RL   L=(XY+o)    */
+       case 0x16: v = RL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;          /* RL   (XY+o)      */
+       case 0x17: A = RL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;          /* RL   A=(XY+o)    */
+       case 0x18: B = RR(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;          /* RR   B=(XY+o)    */
+       case 0x19: C = RR(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;          /* RR   C=(XY+o)    */
+       case 0x1a: D = RR(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;          /* RR   D=(XY+o)    */
+       case 0x1b: E = RR(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;          /* RR   E=(XY+o)    */
+       case 0x1c: H = RR(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;          /* RR   H=(XY+o)    */
+       case 0x1d: L = RR(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;          /* RR   L=(XY+o)    */
+       case 0x1e: v = RR(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;          /* RR   (XY+o)      */
+       case 0x1f: A = RR(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;          /* RR   A=(XY+o)    */
+       case 0x20: B = SLA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;         /* SLA  B=(XY+o)    */
+       case 0x21: C = SLA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;         /* SLA  C=(XY+o)    */
+       case 0x22: D = SLA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;         /* SLA  D=(XY+o)    */
+       case 0x23: E = SLA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;         /* SLA  E=(XY+o)    */
+       case 0x24: H = SLA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;         /* SLA  H=(XY+o)    */
+       case 0x25: L = SLA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;         /* SLA  L=(XY+o)    */
+       case 0x26: v = SLA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;         /* SLA  (XY+o)      */
+       case 0x27: A = SLA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;         /* SLA  A=(XY+o)    */
+       case 0x28: B = SRA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;         /* SRA  B=(XY+o)    */
+       case 0x29: C = SRA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;         /* SRA  C=(XY+o)    */
+       case 0x2a: D = SRA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;         /* SRA  D=(XY+o)    */
+       case 0x2b: E = SRA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;         /* SRA  E=(XY+o)    */
+       case 0x2c: H = SRA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;         /* SRA  H=(XY+o)    */
+       case 0x2d: L = SRA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;         /* SRA  L=(XY+o)    */
+       case 0x2e: v = SRA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;         /* SRA  (XY+o)      */
+       case 0x2f: A = SRA(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;         /* SRA  A=(XY+o)    */
+       case 0x30: B = SLL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;         /* SLL  B=(XY+o)    */
+       case 0x31: C = SLL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;         /* SLL  C=(XY+o)    */
+       case 0x32: D = SLL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;         /* SLL  D=(XY+o)    */
+       case 0x33: E = SLL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;         /* SLL  E=(XY+o)    */
+       case 0x34: H = SLL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;         /* SLL  H=(XY+o)    */
+       case 0x35: L = SLL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;         /* SLL  L=(XY+o)    */
+       case 0x36: v = SLL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;         /* SLL  (XY+o)      */
+       case 0x37: A = SLL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;         /* SLL  A=(XY+o)    */
+       case 0x38: B = SRL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;         /* SRL  B=(XY+o)    */
+       case 0x39: C = SRL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;         /* SRL  C=(XY+o)    */
+       case 0x3a: D = SRL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;         /* SRL  D=(XY+o)    */
+       case 0x3b: E = SRL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;         /* SRL  E=(XY+o)    */
+       case 0x3c: H = SRL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;         /* SRL  H=(XY+o)    */
+       case 0x3d: L = SRL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;         /* SRL  L=(XY+o)    */
+       case 0x3e: v = SRL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;         /* SRL  (XY+o)      */
+       case 0x3f: A = SRL(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;         /* SRL  A=(XY+o)    */
+       case 0x40: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(0, v); break;            /* BIT  0,(XY+o)    */
+       case 0x41: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(0, v); break;            /* BIT  0,(XY+o)    */
+       case 0x42: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(0, v); break;            /* BIT  0,(XY+o)    */
+       case 0x43: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(0, v); break;            /* BIT  0,(XY+o)    */
+       case 0x44: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(0, v); break;            /* BIT  0,(XY+o)    */
+       case 0x45: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(0, v); break;            /* BIT  0,(XY+o)    */
+       case 0x46: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(0, v); break;            /* BIT  0,(XY+o)    */
+       case 0x47: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(0, v); break;            /* BIT  0,(XY+o)    */
+       case 0x48: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(1, v); break;            /* BIT  1,(XY+o)    */
+       case 0x49: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(1, v); break;            /* BIT  1,(XY+o)    */
+       case 0x4a: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(1, v); break;            /* BIT  1,(XY+o)    */
+       case 0x4b: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(1, v); break;            /* BIT  1,(XY+o)    */
+       case 0x4c: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(1, v); break;            /* BIT  1,(XY+o)    */
+       case 0x4d: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(1, v); break;            /* BIT  1,(XY+o)    */
+       case 0x4e: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(1, v); break;            /* BIT  1,(XY+o)    */
+       case 0x4f: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(1, v); break;            /* BIT  1,(XY+o)    */
+       case 0x50: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(2, v); break;            /* BIT  2,(XY+o)    */
+       case 0x51: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(2, v); break;            /* BIT  2,(XY+o)    */
+       case 0x52: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(2, v); break;            /* BIT  2,(XY+o)    */
+       case 0x53: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(2, v); break;            /* BIT  2,(XY+o)    */
+       case 0x54: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(2, v); break;            /* BIT  2,(XY+o)    */
+       case 0x55: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(2, v); break;            /* BIT  2,(XY+o)    */
+       case 0x56: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(2, v); break;            /* BIT  2,(XY+o)    */
+       case 0x57: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(2, v); break;            /* BIT  2,(XY+o)    */
+       case 0x58: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(3, v); break;            /* BIT  3,(XY+o)    */
+       case 0x59: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(3, v); break;            /* BIT  3,(XY+o)    */
+       case 0x5a: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(3, v); break;            /* BIT  3,(XY+o)    */
+       case 0x5b: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(3, v); break;            /* BIT  3,(XY+o)    */
+       case 0x5c: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(3, v); break;            /* BIT  3,(XY+o)    */
+       case 0x5d: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(3, v); break;            /* BIT  3,(XY+o)    */
+       case 0x5e: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(3, v); break;            /* BIT  3,(XY+o)    */
+       case 0x5f: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(3, v); break;            /* BIT  3,(XY+o)    */
+       case 0x60: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(4, v); break;            /* BIT  4,(XY+o)    */
+       case 0x61: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(4, v); break;            /* BIT  4,(XY+o)    */
+       case 0x62: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(4, v); break;            /* BIT  4,(XY+o)    */
+       case 0x63: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(4, v); break;            /* BIT  4,(XY+o)    */
+       case 0x64: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(4, v); break;            /* BIT  4,(XY+o)    */
+       case 0x65: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(4, v); break;            /* BIT  4,(XY+o)    */
+       case 0x66: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(4, v); break;            /* BIT  4,(XY+o)    */
+       case 0x67: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(4, v); break;            /* BIT  4,(XY+o)    */
+       case 0x68: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(5, v); break;            /* BIT  5,(XY+o)    */
+       case 0x69: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(5, v); break;            /* BIT  5,(XY+o)    */
+       case 0x6a: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(5, v); break;            /* BIT  5,(XY+o)    */
+       case 0x6b: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(5, v); break;            /* BIT  5,(XY+o)    */
+       case 0x6c: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(5, v); break;            /* BIT  5,(XY+o)    */
+       case 0x6d: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(5, v); break;            /* BIT  5,(XY+o)    */
+       case 0x6e: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(5, v); break;            /* BIT  5,(XY+o)    */
+       case 0x6f: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(5, v); break;            /* BIT  5,(XY+o)    */
+       case 0x70: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(6, v); break;            /* BIT  6,(XY+o)    */
+       case 0x71: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(6, v); break;            /* BIT  6,(XY+o)    */
+       case 0x72: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(6, v); break;            /* BIT  6,(XY+o)    */
+       case 0x73: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(6, v); break;            /* BIT  6,(XY+o)    */
+       case 0x74: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(6, v); break;            /* BIT  6,(XY+o)    */
+       case 0x75: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(6, v); break;            /* BIT  6,(XY+o)    */
+       case 0x76: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(6, v); break;            /* BIT  6,(XY+o)    */
+       case 0x77: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(6, v); break;            /* BIT  6,(XY+o)    */
+       case 0x78: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(7, v); break;            /* BIT  7,(XY+o)    */
+       case 0x79: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(7, v); break;            /* BIT  7,(XY+o)    */
+       case 0x7a: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(7, v); break;            /* BIT  7,(XY+o)    */
+       case 0x7b: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(7, v); break;            /* BIT  7,(XY+o)    */
+       case 0x7c: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(7, v); break;            /* BIT  7,(XY+o)    */
+       case 0x7d: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(7, v); break;            /* BIT  7,(XY+o)    */
+       case 0x7e: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(7, v); break;            /* BIT  7,(XY+o)    */
+       case 0x7f: v = RM8(ea); CLOCK_IN_OP(1); BIT_XY(7, v); break;            /* BIT  7,(XY+o)    */
+       case 0x80: B = RES(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* RES  0,B=(XY+o)  */
+       case 0x81: C = RES(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* RES  0,C=(XY+o)  */
+       case 0x82: D = RES(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* RES  0,D=(XY+o)  */
+       case 0x83: E = RES(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* RES  0,E=(XY+o)  */
+       case 0x84: H = RES(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* RES  0,H=(XY+o)  */
+       case 0x85: L = RES(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* RES  0,L=(XY+o)  */
+       case 0x86: v = RES(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* RES  0,(XY+o)    */
+       case 0x87: A = RES(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* RES  0,A=(XY+o)  */
+       case 0x88: B = RES(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* RES  1,B=(XY+o)  */
+       case 0x89: C = RES(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* RES  1,C=(XY+o)  */
+       case 0x8a: D = RES(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* RES  1,D=(XY+o)  */
+       case 0x8b: E = RES(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* RES  1,E=(XY+o)  */
+       case 0x8c: H = RES(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* RES  1,H=(XY+o)  */
+       case 0x8d: L = RES(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* RES  1,L=(XY+o)  */
+       case 0x8e: v = RES(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* RES  1,(XY+o)    */
+       case 0x8f: A = RES(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* RES  1,A=(XY+o)  */
+       case 0x90: B = RES(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* RES  2,B=(XY+o)  */
+       case 0x91: C = RES(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* RES  2,C=(XY+o)  */
+       case 0x92: D = RES(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* RES  2,D=(XY+o)  */
+       case 0x93: E = RES(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* RES  2,E=(XY+o)  */
+       case 0x94: H = RES(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* RES  2,H=(XY+o)  */
+       case 0x95: L = RES(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* RES  2,L=(XY+o)  */
+       case 0x96: v = RES(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* RES  2,(XY+o)    */
+       case 0x97: A = RES(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* RES  2,A=(XY+o)  */
+       case 0x98: B = RES(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* RES  3,B=(XY+o)  */
+       case 0x99: C = RES(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* RES  3,C=(XY+o)  */
+       case 0x9a: D = RES(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* RES  3,D=(XY+o)  */
+       case 0x9b: E = RES(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* RES  3,E=(XY+o)  */
+       case 0x9c: H = RES(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* RES  3,H=(XY+o)  */
+       case 0x9d: L = RES(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* RES  3,L=(XY+o)  */
+       case 0x9e: v = RES(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* RES  3,(XY+o)    */
+       case 0x9f: A = RES(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* RES  3,A=(XY+o)  */
+       case 0xa0: B = RES(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* RES  4,B=(XY+o)  */
+       case 0xa1: C = RES(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* RES  4,C=(XY+o)  */
+       case 0xa2: D = RES(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* RES  4,D=(XY+o)  */
+       case 0xa3: E = RES(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* RES  4,E=(XY+o)  */
+       case 0xa4: H = RES(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* RES  4,H=(XY+o)  */
+       case 0xa5: L = RES(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* RES  4,L=(XY+o)  */
+       case 0xa6: v = RES(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* RES  4,(XY+o)    */
+       case 0xa7: A = RES(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* RES  4,A=(XY+o)  */
+       case 0xa8: B = RES(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* RES  5,B=(XY+o)  */
+       case 0xa9: C = RES(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* RES  5,C=(XY+o)  */
+       case 0xaa: D = RES(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* RES  5,D=(XY+o)  */
+       case 0xab: E = RES(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* RES  5,E=(XY+o)  */
+       case 0xac: H = RES(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* RES  5,H=(XY+o)  */
+       case 0xad: L = RES(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* RES  5,L=(XY+o)  */
+       case 0xae: v = RES(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* RES  5,(XY+o)    */
+       case 0xaf: A = RES(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* RES  5,A=(XY+o)  */
+       case 0xb0: B = RES(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* RES  6,B=(XY+o)  */
+       case 0xb1: C = RES(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* RES  6,C=(XY+o)  */
+       case 0xb2: D = RES(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* RES  6,D=(XY+o)  */
+       case 0xb3: E = RES(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* RES  6,E=(XY+o)  */
+       case 0xb4: H = RES(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* RES  6,H=(XY+o)  */
+       case 0xb5: L = RES(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* RES  6,L=(XY+o)  */
+       case 0xb6: v = RES(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* RES  6,(XY+o)    */
+       case 0xb7: A = RES(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* RES  6,A=(XY+o)  */
+       case 0xb8: B = RES(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* RES  7,B=(XY+o)  */
+       case 0xb9: C = RES(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* RES  7,C=(XY+o)  */
+       case 0xba: D = RES(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* RES  7,D=(XY+o)  */
+       case 0xbb: E = RES(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* RES  7,E=(XY+o)  */
+       case 0xbc: H = RES(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* RES  7,H=(XY+o)  */
+       case 0xbd: L = RES(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* RES  7,L=(XY+o)  */
+       case 0xbe: v = RES(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* RES  7,(XY+o)    */
+       case 0xbf: A = RES(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* RES  7,A=(XY+o)  */
+       case 0xc0: B = SET(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* SET  0,B=(XY+o)  */
+       case 0xc1: C = SET(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* SET  0,C=(XY+o)  */
+       case 0xc2: D = SET(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* SET  0,D=(XY+o)  */
+       case 0xc3: E = SET(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* SET  0,E=(XY+o)  */
+       case 0xc4: H = SET(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* SET  0,H=(XY+o)  */
+       case 0xc5: L = SET(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* SET  0,L=(XY+o)  */
+       case 0xc6: v = SET(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* SET  0,(XY+o)    */
+       case 0xc7: A = SET(0, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* SET  0,A=(XY+o)  */
+       case 0xc8: B = SET(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* SET  1,B=(XY+o)  */
+       case 0xc9: C = SET(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* SET  1,C=(XY+o)  */
+       case 0xca: D = SET(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* SET  1,D=(XY+o)  */
+       case 0xcb: E = SET(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* SET  1,E=(XY+o)  */
+       case 0xcc: H = SET(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* SET  1,H=(XY+o)  */
+       case 0xcd: L = SET(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* SET  1,L=(XY+o)  */
+       case 0xce: v = SET(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* SET  1,(XY+o)    */
+       case 0xcf: A = SET(1, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* SET  1,A=(XY+o)  */
+       case 0xd0: B = SET(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* SET  2,B=(XY+o)  */
+       case 0xd1: C = SET(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* SET  2,C=(XY+o)  */
+       case 0xd2: D = SET(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* SET  2,D=(XY+o)  */
+       case 0xd3: E = SET(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* SET  2,E=(XY+o)  */
+       case 0xd4: H = SET(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* SET  2,H=(XY+o)  */
+       case 0xd5: L = SET(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* SET  2,L=(XY+o)  */
+       case 0xd6: v = SET(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* SET  2,(XY+o)    */
+       case 0xd7: A = SET(2, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* SET  2,A=(XY+o)  */
+       case 0xd8: B = SET(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* SET  3,B=(XY+o)  */
+       case 0xd9: C = SET(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* SET  3,C=(XY+o)  */
+       case 0xda: D = SET(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* SET  3,D=(XY+o)  */
+       case 0xdb: E = SET(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* SET  3,E=(XY+o)  */
+       case 0xdc: H = SET(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* SET  3,H=(XY+o)  */
+       case 0xdd: L = SET(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* SET  3,L=(XY+o)  */
+       case 0xde: v = SET(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* SET  3,(XY+o)    */
+       case 0xdf: A = SET(3, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* SET  3,A=(XY+o)  */
+       case 0xe0: B = SET(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* SET  4,B=(XY+o)  */
+       case 0xe1: C = SET(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* SET  4,C=(XY+o)  */
+       case 0xe2: D = SET(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* SET  4,D=(XY+o)  */
+       case 0xe3: E = SET(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* SET  4,E=(XY+o)  */
+       case 0xe4: H = SET(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* SET  4,H=(XY+o)  */
+       case 0xe5: L = SET(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* SET  4,L=(XY+o)  */
+       case 0xe6: v = SET(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* SET  4,(XY+o)    */
+       case 0xe7: A = SET(4, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* SET  4,A=(XY+o)  */
+       case 0xe8: B = SET(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* SET  5,B=(XY+o)  */
+       case 0xe9: C = SET(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* SET  5,C=(XY+o)  */
+       case 0xea: D = SET(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* SET  5,D=(XY+o)  */
+       case 0xeb: E = SET(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* SET  5,E=(XY+o)  */
+       case 0xec: H = SET(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* SET  5,H=(XY+o)  */
+       case 0xed: L = SET(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* SET  5,L=(XY+o)  */
+       case 0xee: v = SET(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* SET  5,(XY+o)    */
+       case 0xef: A = SET(5, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* SET  5,A=(XY+o)  */
+       case 0xf0: B = SET(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* SET  6,B=(XY+o)  */
+       case 0xf1: C = SET(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* SET  6,C=(XY+o)  */
+       case 0xf2: D = SET(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* SET  6,D=(XY+o)  */
+       case 0xf3: E = SET(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* SET  6,E=(XY+o)  */
+       case 0xf4: H = SET(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* SET  6,H=(XY+o)  */
+       case 0xf5: L = SET(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* SET  6,L=(XY+o)  */
+       case 0xf6: v = SET(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* SET  6,(XY+o)    */
+       case 0xf7: A = SET(6, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* SET  6,A=(XY+o)  */
+       case 0xf8: B = SET(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, B); break;      /* SET  7,B=(XY+o)  */
+       case 0xf9: C = SET(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, C); break;      /* SET  7,C=(XY+o)  */
+       case 0xfa: D = SET(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, D); break;      /* SET  7,D=(XY+o)  */
+       case 0xfb: E = SET(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, E); break;      /* SET  7,E=(XY+o)  */
+       case 0xfc: H = SET(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, H); break;      /* SET  7,H=(XY+o)  */
+       case 0xfd: L = SET(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, L); break;      /* SET  7,L=(XY+o)  */
+       case 0xfe: v = SET(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;      /* SET  7,(XY+o)    */
+       case 0xff: A = SET(7, RM8(ea)); CLOCK_IN_OP(1); WM8(ea, A); break;      /* SET  7,A=(XY+o)  */
 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
        default: __assume(0);
 #endif
@@ -1345,198 +1366,205 @@ void Z80::OP_XY(uint8_t code)
 
 void Z80::OP_DD(uint8_t code)
 {
+       // Done: M1 + M1
+       uint8_t v;
+
        icount -= cc_xy[code];
-       
+
        switch(code) {
-       case 0x09: ADD16(ix, bc); break;                                /* ADD  IX,BC       */
-       case 0x19: ADD16(ix, de); break;                                /* ADD  IX,DE       */
-       case 0x21: IX = FETCH16(); break;                               /* LD   IX,w        */
-       case 0x22: ea = FETCH16(); WM16(ea, &ix); WZ = ea + 1; break;   /* LD   (w),IX      */
-       case 0x23: IX++; break;                                         /* INC  IX          */
-       case 0x24: HX = INC(HX); break;                                 /* INC  HX          */
-       case 0x25: HX = DEC(HX); break;                                 /* DEC  HX          */
-       case 0x26: HX = FETCH8(); break;                                /* LD   HX,n        */
-       case 0x29: ADD16(ix, ix); break;                                /* ADD  IX,IX       */
-       case 0x2a: ea = FETCH16(); RM16(ea, &ix); WZ = ea + 1; break;   /* LD   IX,(w)      */
-       case 0x2b: IX--; break;                                         /* DEC  IX          */
-       case 0x2c: LX = INC(LX); break;                                 /* INC  LX          */
-       case 0x2d: LX = DEC(LX); break;                                 /* DEC  LX          */
-       case 0x2e: LX = FETCH8(); break;                                /* LD   LX,n        */
-       case 0x34: EAX(); WM8(ea, INC(RM8(ea))); break;                 /* INC  (IX+o)      */
-       case 0x35: EAX(); WM8(ea, DEC(RM8(ea))); break;                 /* DEC  (IX+o)      */
-       case 0x36: EAX(); WM8(ea, FETCH8()); break;                     /* LD   (IX+o),n    */
-       case 0x39: ADD16(ix, sp); break;                                /* ADD  IX,SP       */
-       case 0x44: B = HX; break;                                       /* LD   B,HX        */
-       case 0x45: B = LX; break;                                       /* LD   B,LX        */
-       case 0x46: EAX(); B = RM8(ea); break;                           /* LD   B,(IX+o)    */
-       case 0x4c: C = HX; break;                                       /* LD   C,HX        */
-       case 0x4d: C = LX; break;                                       /* LD   C,LX        */
-       case 0x4e: EAX(); C = RM8(ea); break;                           /* LD   C,(IX+o)    */
-       case 0x54: D = HX; break;                                       /* LD   D,HX        */
-       case 0x55: D = LX; break;                                       /* LD   D,LX        */
-       case 0x56: EAX(); D = RM8(ea); break;                           /* LD   D,(IX+o)    */
-       case 0x5c: E = HX; break;                                       /* LD   E,HX        */
-       case 0x5d: E = LX; break;                                       /* LD   E,LX        */
-       case 0x5e: EAX(); E = RM8(ea); break;                           /* LD   E,(IX+o)    */
-       case 0x60: HX = B; break;                                       /* LD   HX,B        */
-       case 0x61: HX = C; break;                                       /* LD   HX,C        */
-       case 0x62: HX = D; break;                                       /* LD   HX,D        */
-       case 0x63: HX = E; break;                                       /* LD   HX,E        */
-       case 0x64: break;                                               /* LD   HX,HX       */
-       case 0x65: HX = LX; break;                                      /* LD   HX,LX       */
-       case 0x66: EAX(); H = RM8(ea); break;                           /* LD   H,(IX+o)    */
-       case 0x67: HX = A; break;                                       /* LD   HX,A        */
-       case 0x68: LX = B; break;                                       /* LD   LX,B        */
-       case 0x69: LX = C; break;                                       /* LD   LX,C        */
-       case 0x6a: LX = D; break;                                       /* LD   LX,D        */
-       case 0x6b: LX = E; break;                                       /* LD   LX,E        */
-       case 0x6c: LX = HX; break;                                      /* LD   LX,HX       */
-       case 0x6d: break;                                               /* LD   LX,LX       */
-       case 0x6e: EAX(); L = RM8(ea); break;                           /* LD   L,(IX+o)    */
-       case 0x6f: LX = A; break;                                       /* LD   LX,A        */
-       case 0x70: EAX(); WM8(ea, B); break;                            /* LD   (IX+o),B    */
-       case 0x71: EAX(); WM8(ea, C); break;                            /* LD   (IX+o),C    */
-       case 0x72: EAX(); WM8(ea, D); break;                            /* LD   (IX+o),D    */
-       case 0x73: EAX(); WM8(ea, E); break;                            /* LD   (IX+o),E    */
-       case 0x74: EAX(); WM8(ea, H); break;                            /* LD   (IX+o),H    */
-       case 0x75: EAX(); WM8(ea, L); break;                            /* LD   (IX+o),L    */
-       case 0x77: EAX(); WM8(ea, A); break;                            /* LD   (IX+o),A    */
-       case 0x7c: A = HX; break;                                       /* LD   A,HX        */
-       case 0x7d: A = LX; break;                                       /* LD   A,LX        */
-       case 0x7e: EAX(); A = RM8(ea); break;                           /* LD   A,(IX+o)    */
-       case 0x84: ADD(HX); break;                                      /* ADD  A,HX        */
-       case 0x85: ADD(LX); break;                                      /* ADD  A,LX        */
-       case 0x86: EAX(); ADD(RM8(ea)); break;                          /* ADD  A,(IX+o)    */
-       case 0x8c: ADC(HX); break;                                      /* ADC  A,HX        */
-       case 0x8d: ADC(LX); break;                                      /* ADC  A,LX        */
-       case 0x8e: EAX(); ADC(RM8(ea)); break;                          /* ADC  A,(IX+o)    */
-       case 0x94: SUB(HX); break;                                      /* SUB  HX          */
-       case 0x95: SUB(LX); break;                                      /* SUB  LX          */
-       case 0x96: EAX(); SUB(RM8(ea)); break;                          /* SUB  (IX+o)      */
-       case 0x9c: SBC(HX); break;                                      /* SBC  A,HX        */
-       case 0x9d: SBC(LX); break;                                      /* SBC  A,LX        */
-       case 0x9e: EAX(); SBC(RM8(ea)); break;                          /* SBC  A,(IX+o)    */
-       case 0xa4: AND(HX); break;                                      /* AND  HX          */
-       case 0xa5: AND(LX); break;                                      /* AND  LX          */
-       case 0xa6: EAX(); AND(RM8(ea)); break;                          /* AND  (IX+o)      */
-       case 0xac: XOR(HX); break;                                      /* XOR  HX          */
-       case 0xad: XOR(LX); break;                                      /* XOR  LX          */
-       case 0xae: EAX(); XOR(RM8(ea)); break;                          /* XOR  (IX+o)      */
-       case 0xb4: OR(HX); break;                                       /* OR   HX          */
-       case 0xb5: OR(LX); break;                                       /* OR   LX          */
-       case 0xb6: EAX(); OR(RM8(ea)); break;                           /* OR   (IX+o)      */
-       case 0xbc: CP(HX); break;                                       /* CP   HX          */
-       case 0xbd: CP(LX); break;                                       /* CP   LX          */
-       case 0xbe: EAX(); CP(RM8(ea)); break;                           /* CP   (IX+o)      */
-       case 0xcb: EAX(); OP_XY(FETCH8()); break;                       /* **   DD CB xx    */
-       case 0xe1: POP(ix); break;                                      /* POP  IX          */
-       case 0xe3: EXSP(ix); break;                                     /* EX   (SP),IX     */
-       case 0xe5: PUSH(ix); break;                                     /* PUSH IX          */
-       case 0xe9: PC = IX; break;                                      /* JP   (IX)        */
-       case 0xf9: SP = IX; break;                                      /* LD   SP,IX       */
+       case 0x09: ADD16(ix, bc); break;                                        /* ADD  IX,BC       */
+       case 0x19: ADD16(ix, de); break;                                        /* ADD  IX,DE       */
+       case 0x21: IX = FETCH16(); break;                                       /* LD   IX,w        */
+       case 0x22: ea = FETCH16(); WM16(ea, &ix); WZ = ea + 1; break;           /* LD   (w),IX      */
+       case 0x23: IX++; break;                                                 /* INC  IX          */
+       case 0x24: HX = INC(HX); break;                                         /* INC  HX          */
+       case 0x25: HX = DEC(HX); break;                                         /* DEC  HX          */
+       case 0x26: HX = FETCH8(); break;                                        /* LD   HX,n        */
+       case 0x29: ADD16(ix, ix); break;                                        /* ADD  IX,IX       */
+       case 0x2a: ea = FETCH16(); RM16(ea, &ix); WZ = ea + 1; break;           /* LD   IX,(w)      */
+       case 0x2b: IX--; break;                                                 /* DEC  IX          */
+       case 0x2c: LX = INC(LX); break;                                         /* INC  LX          */
+       case 0x2d: LX = DEC(LX); break;                                         /* DEC  LX          */
+       case 0x2e: LX = FETCH8(); break;                                        /* LD   LX,n        */
+       case 0x34: EAX(); CLOCK_IN_OP(5); v = INC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;  /* INC  (IX+o)      */
+       case 0x35: EAX(); CLOCK_IN_OP(5); v = DEC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;  /* DEC  (IX+o)      */
+       case 0x36: EAX(); v = FETCH8(); CLOCK_IN_OP(2); WM8(ea, v); break;      /* LD   (IX+o),n    */
+       case 0x39: ADD16(ix, sp); break;                                        /* ADD  IX,SP       */
+       case 0x44: B = HX; break;                                               /* LD   B,HX        */
+       case 0x45: B = LX; break;                                               /* LD   B,LX        */
+       case 0x46: EAX(); CLOCK_IN_OP(5); B = RM8(ea); break;                   /* LD   B,(IX+o)    */
+       case 0x4c: C = HX; break;                                               /* LD   C,HX        */
+       case 0x4d: C = LX; break;                                               /* LD   C,LX        */
+       case 0x4e: EAX(); CLOCK_IN_OP(5); C = RM8(ea); break;                   /* LD   C,(IX+o)    */
+       case 0x54: D = HX; break;                                               /* LD   D,HX        */
+       case 0x55: D = LX; break;                                               /* LD   D,LX        */
+       case 0x56: EAX(); CLOCK_IN_OP(5); D = RM8(ea); break;                   /* LD   D,(IX+o)    */
+       case 0x5c: E = HX; break;                                               /* LD   E,HX        */
+       case 0x5d: E = LX; break;                                               /* LD   E,LX        */
+       case 0x5e: EAX(); CLOCK_IN_OP(5); E = RM8(ea); break;                   /* LD   E,(IX+o)    */
+       case 0x60: HX = B; break;                                               /* LD   HX,B        */
+       case 0x61: HX = C; break;                                               /* LD   HX,C        */
+       case 0x62: HX = D; break;                                               /* LD   HX,D        */
+       case 0x63: HX = E; break;                                               /* LD   HX,E        */
+       case 0x64: break;                                                       /* LD   HX,HX       */
+       case 0x65: HX = LX; break;                                              /* LD   HX,LX       */
+       case 0x66: EAX(); CLOCK_IN_OP(5); H = RM8(ea); break;                   /* LD   H,(IX+o)    */
+       case 0x67: HX = A; break;                                               /* LD   HX,A        */
+       case 0x68: LX = B; break;                                               /* LD   LX,B        */
+       case 0x69: LX = C; break;                                               /* LD   LX,C        */
+       case 0x6a: LX = D; break;                                               /* LD   LX,D        */
+       case 0x6b: LX = E; break;                                               /* LD   LX,E        */
+       case 0x6c: LX = HX; break;                                              /* LD   LX,HX       */
+       case 0x6d: break;                                                       /* LD   LX,LX       */
+       case 0x6e: EAX(); CLOCK_IN_OP(5); L = RM8(ea); break;                   /* LD   L,(IX+o)    */
+       case 0x6f: LX = A; break;                                               /* LD   LX,A        */
+       case 0x70: EAX(); CLOCK_IN_OP(5); WM8(ea, B); break;                    /* LD   (IX+o),B    */
+       case 0x71: EAX(); CLOCK_IN_OP(5); WM8(ea, C); break;                    /* LD   (IX+o),C    */
+       case 0x72: EAX(); CLOCK_IN_OP(5); WM8(ea, D); break;                    /* LD   (IX+o),D    */
+       case 0x73: EAX(); CLOCK_IN_OP(5); WM8(ea, E); break;                    /* LD   (IX+o),E    */
+       case 0x74: EAX(); CLOCK_IN_OP(5); WM8(ea, H); break;                    /* LD   (IX+o),H    */
+       case 0x75: EAX(); CLOCK_IN_OP(5); WM8(ea, L); break;                    /* LD   (IX+o),L    */
+       case 0x77: EAX(); CLOCK_IN_OP(5); WM8(ea, A); break;                    /* LD   (IX+o),A    */
+       case 0x7c: A = HX; break;                                               /* LD   A,HX        */
+       case 0x7d: A = LX; break;                                               /* LD   A,LX        */
+       case 0x7e: EAX(); CLOCK_IN_OP(5); A = RM8(ea); break;                   /* LD   A,(IX+o)    */
+       case 0x84: ADD(HX); break;                                              /* ADD  A,HX        */
+       case 0x85: ADD(LX); break;                                              /* ADD  A,LX        */
+       case 0x86: EAX(); CLOCK_IN_OP(5); ADD(RM8(ea)); break;                  /* ADD  A,(IX+o)    */
+       case 0x8c: ADC(HX); break;                                              /* ADC  A,HX        */
+       case 0x8d: ADC(LX); break;                                              /* ADC  A,LX        */
+       case 0x8e: EAX(); CLOCK_IN_OP(5); ADC(RM8(ea)); break;                  /* ADC  A,(IX+o)    */
+       case 0x94: SUB(HX); break;                                              /* SUB  HX          */
+       case 0x95: SUB(LX); break;                                              /* SUB  LX          */
+       case 0x96: EAX(); CLOCK_IN_OP(5); SUB(RM8(ea)); break;                  /* SUB  (IX+o)      */
+       case 0x9c: SBC(HX); break;                                              /* SBC  A,HX        */
+       case 0x9d: SBC(LX); break;                                              /* SBC  A,LX        */
+       case 0x9e: EAX(); CLOCK_IN_OP(5); SBC(RM8(ea)); break;                  /* SBC  A,(IX+o)    */
+       case 0xa4: AND(HX); break;                                              /* AND  HX          */
+       case 0xa5: AND(LX); break;                                              /* AND  LX          */
+       case 0xa6: EAX(); CLOCK_IN_OP(5); AND(RM8(ea)); break;                  /* AND  (IX+o)      */
+       case 0xac: XOR(HX); break;                                              /* XOR  HX          */
+       case 0xad: XOR(LX); break;                                              /* XOR  LX          */
+       case 0xae: EAX(); CLOCK_IN_OP(5); XOR(RM8(ea)); break;                  /* XOR  (IX+o)      */
+       case 0xb4: OR(HX); break;                                               /* OR   HX          */
+       case 0xb5: OR(LX); break;                                               /* OR   LX          */
+       case 0xb6: EAX(); CLOCK_IN_OP(5); OR(RM8(ea)); break;                   /* OR   (IX+o)      */
+       case 0xbc: CP(HX); break;                                               /* CP   HX          */
+       case 0xbd: CP(LX); break;                                               /* CP   LX          */
+       case 0xbe: EAX(); CLOCK_IN_OP(5); CP(RM8(ea)); break;                   /* CP   (IX+o)      */
+       case 0xcb: EAX(); v = FETCH8(); CLOCK_IN_OP(2); OP_XY(v); break;        /* **   DD CB xx    */
+       case 0xe1: POP(ix); break;                                              /* POP  IX          */
+       case 0xe3: EXSP(ix); break;                                             /* EX   (SP),IX     */
+       case 0xe5: PUSH(ix); break;                                             /* PUSH IX          */
+       case 0xe9: PC = IX; break;                                              /* JP   (IX)        */
+       case 0xf9: SP = IX; break;                                              /* LD   SP,IX       */
        default:   OP(code); break;
        }
 }
 
 void Z80::OP_FD(uint8_t code)
 {
+       // Done: M1 + M1
+       uint8_t v;
+
        icount -= cc_xy[code];
-       
+
        switch(code) {
-       case 0x09: ADD16(iy, bc); break;                                /* ADD  IY,BC       */
-       case 0x19: ADD16(iy, de); break;                                /* ADD  IY,DE       */
-       case 0x21: IY = FETCH16(); break;                               /* LD   IY,w        */
-       case 0x22: ea = FETCH16(); WM16(ea, &iy); WZ = ea + 1; break;   /* LD   (w),IY      */
-       case 0x23: IY++; break;                                         /* INC  IY          */
-       case 0x24: HY = INC(HY); break;                                 /* INC  HY          */
-       case 0x25: HY = DEC(HY); break;                                 /* DEC  HY          */
-       case 0x26: HY = FETCH8(); break;                                /* LD   HY,n        */
-       case 0x29: ADD16(iy, iy); break;                                /* ADD  IY,IY       */
-       case 0x2a: ea = FETCH16(); RM16(ea, &iy); WZ = ea + 1; break;   /* LD   IY,(w)      */
-       case 0x2b: IY--; break;                                         /* DEC  IY          */
-       case 0x2c: LY = INC(LY); break;                                 /* INC  LY          */
-       case 0x2d: LY = DEC(LY); break;                                 /* DEC  LY          */
-       case 0x2e: LY = FETCH8(); break;                                /* LD   LY,n        */
-       case 0x34: EAY(); WM8(ea, INC(RM8(ea))); break;                 /* INC  (IY+o)      */
-       case 0x35: EAY(); WM8(ea, DEC(RM8(ea))); break;                 /* DEC  (IY+o)      */
-       case 0x36: EAY(); WM8(ea, FETCH8()); break;                     /* LD   (IY+o),n    */
-       case 0x39: ADD16(iy, sp); break;                                /* ADD  IY,SP       */
-       case 0x44: B = HY; break;                                       /* LD   B,HY        */
-       case 0x45: B = LY; break;                                       /* LD   B,LY        */
-       case 0x46: EAY(); B = RM8(ea); break;                           /* LD   B,(IY+o)    */
-       case 0x4c: C = HY; break;                                       /* LD   C,HY        */
-       case 0x4d: C = LY; break;                                       /* LD   C,LY        */
-       case 0x4e: EAY(); C = RM8(ea); break;                           /* LD   C,(IY+o)    */
-       case 0x54: D = HY; break;                                       /* LD   D,HY        */
-       case 0x55: D = LY; break;                                       /* LD   D,LY        */
-       case 0x56: EAY(); D = RM8(ea); break;                           /* LD   D,(IY+o)    */
-       case 0x5c: E = HY; break;                                       /* LD   E,HY        */
-       case 0x5d: E = LY; break;                                       /* LD   E,LY        */
-       case 0x5e: EAY(); E = RM8(ea); break;                           /* LD   E,(IY+o)    */
-       case 0x60: HY = B; break;                                       /* LD   HY,B        */
-       case 0x61: HY = C; break;                                       /* LD   HY,C        */
-       case 0x62: HY = D; break;                                       /* LD   HY,D        */
-       case 0x63: HY = E; break;                                       /* LD   HY,E        */
-       case 0x64: break;                                               /* LD   HY,HY       */
-       case 0x65: HY = LY; break;                                      /* LD   HY,LY       */
-       case 0x66: EAY(); H = RM8(ea); break;                           /* LD   H,(IY+o)    */
-       case 0x67: HY = A; break;                                       /* LD   HY,A        */
-       case 0x68: LY = B; break;                                       /* LD   LY,B        */
-       case 0x69: LY = C; break;                                       /* LD   LY,C        */
-       case 0x6a: LY = D; break;                                       /* LD   LY,D        */
-       case 0x6b: LY = E; break;                                       /* LD   LY,E        */
-       case 0x6c: LY = HY; break;                                      /* LD   LY,HY       */
-       case 0x6d: break;                                               /* LD   LY,LY       */
-       case 0x6e: EAY(); L = RM8(ea); break;                           /* LD   L,(IY+o)    */
-       case 0x6f: LY = A; break;                                       /* LD   LY,A        */
-       case 0x70: EAY(); WM8(ea, B); break;                            /* LD   (IY+o),B    */
-       case 0x71: EAY(); WM8(ea, C); break;                            /* LD   (IY+o),C    */
-       case 0x72: EAY(); WM8(ea, D); break;                            /* LD   (IY+o),D    */
-       case 0x73: EAY(); WM8(ea, E); break;                            /* LD   (IY+o),E    */
-       case 0x74: EAY(); WM8(ea, H); break;                            /* LD   (IY+o),H    */
-       case 0x75: EAY(); WM8(ea, L); break;                            /* LD   (IY+o),L    */
-       case 0x77: EAY(); WM8(ea, A); break;                            /* LD   (IY+o),A    */
-       case 0x7c: A = HY; break;                                       /* LD   A,HY        */
-       case 0x7d: A = LY; break;                                       /* LD   A,LY        */
-       case 0x7e: EAY(); A = RM8(ea); break;                           /* LD   A,(IY+o)    */
-       case 0x84: ADD(HY); break;                                      /* ADD  A,HY        */
-       case 0x85: ADD(LY); break;                                      /* ADD  A,LY        */
-       case 0x86: EAY(); ADD(RM8(ea)); break;                          /* ADD  A,(IY+o)    */
-       case 0x8c: ADC(HY); break;                                      /* ADC  A,HY        */
-       case 0x8d: ADC(LY); break;                                      /* ADC  A,LY        */
-       case 0x8e: EAY(); ADC(RM8(ea)); break;                          /* ADC  A,(IY+o)    */
-       case 0x94: SUB(HY); break;                                      /* SUB  HY          */
-       case 0x95: SUB(LY); break;                                      /* SUB  LY          */
-       case 0x96: EAY(); SUB(RM8(ea)); break;                          /* SUB  (IY+o)      */
-       case 0x9c: SBC(HY); break;                                      /* SBC  A,HY        */
-       case 0x9d: SBC(LY); break;                                      /* SBC  A,LY        */
-       case 0x9e: EAY(); SBC(RM8(ea)); break;                          /* SBC  A,(IY+o)    */
-       case 0xa4: AND(HY); break;                                      /* AND  HY          */
-       case 0xa5: AND(LY); break;                                      /* AND  LY          */
-       case 0xa6: EAY(); AND(RM8(ea)); break;                          /* AND  (IY+o)      */
-       case 0xac: XOR(HY); break;                                      /* XOR  HY          */
-       case 0xad: XOR(LY); break;                                      /* XOR  LY          */
-       case 0xae: EAY(); XOR(RM8(ea)); break;                          /* XOR  (IY+o)      */
-       case 0xb4: OR(HY); break;                                       /* OR   HY          */
-       case 0xb5: OR(LY); break;                                       /* OR   LY          */
-       case 0xb6: EAY(); OR(RM8(ea)); break;                           /* OR   (IY+o)      */
-       case 0xbc: CP(HY); break;                                       /* CP   HY          */
-       case 0xbd: CP(LY); break;                                       /* CP   LY          */
-       case 0xbe: EAY(); CP(RM8(ea)); break;                           /* CP   (IY+o)      */
-       case 0xcb: EAY(); OP_XY(FETCH8()); break;                       /* **   FD CB xx    */
-       case 0xe1: POP(iy); break;                                      /* POP  IY          */
-       case 0xe3: EXSP(iy); break;                                     /* EX   (SP),IY     */
-       case 0xe5: PUSH(iy); break;                                     /* PUSH IY          */
-       case 0xe9: PC = IY; break;                                      /* JP   (IY)        */
-       case 0xf9: SP = IY; break;                                      /* LD   SP,IY       */
+       case 0x09: ADD16(iy, bc); break;                                        /* ADD  IY,BC       */
+       case 0x19: ADD16(iy, de); break;                                        /* ADD  IY,DE       */
+       case 0x21: IY = FETCH16(); break;                                       /* LD   IY,w        */
+       case 0x22: ea = FETCH16(); WM16(ea, &iy); WZ = ea + 1; break;           /* LD   (w),IY      */
+       case 0x23: IY++; break;                                                 /* INC  IY          */
+       case 0x24: HY = INC(HY); break;                                         /* INC  HY          */
+       case 0x25: HY = DEC(HY); break;                                         /* DEC  HY          */
+       case 0x26: HY = FETCH8(); break;                                        /* LD   HY,n        */
+       case 0x29: ADD16(iy, iy); break;                                        /* ADD  IY,IY       */
+       case 0x2a: ea = FETCH16(); RM16(ea, &iy); WZ = ea + 1; break;           /* LD   IY,(w)      */
+       case 0x2b: IY--; break;                                                 /* DEC  IY          */
+       case 0x2c: LY = INC(LY); break;                                         /* INC  LY          */
+       case 0x2d: LY = DEC(LY); break;                                         /* DEC  LY          */
+       case 0x2e: LY = FETCH8(); break;                                        /* LD   LY,n        */
+       case 0x34: EAY(); CLOCK_IN_OP(5); v = INC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;  /* INC  (IY+o)      */
+       case 0x35: EAY(); CLOCK_IN_OP(5); v = DEC(RM8(ea)); CLOCK_IN_OP(1); WM8(ea, v); break;  /* DEC  (IY+o)      */
+       case 0x36: EAY(); v = FETCH8(); CLOCK_IN_OP(2); WM8(ea, v); break;      /* LD   (IY+o),n    */
+       case 0x39: ADD16(iy, sp); break;                                        /* ADD  IY,SP       */
+       case 0x44: B = HY; break;                                               /* LD   B,HY        */
+       case 0x45: B = LY; break;                                               /* LD   B,LY        */
+       case 0x46: EAY(); CLOCK_IN_OP(5); B = RM8(ea); break;                   /* LD   B,(IY+o)    */
+       case 0x4c: C = HY; break;                                               /* LD   C,HY        */
+       case 0x4d: C = LY; break;                                               /* LD   C,LY        */
+       case 0x4e: EAY(); CLOCK_IN_OP(5); C = RM8(ea); break;                   /* LD   C,(IY+o)    */
+       case 0x54: D = HY; break;                                               /* LD   D,HY        */
+       case 0x55: D = LY; break;                                               /* LD   D,LY        */
+       case 0x56: EAY(); CLOCK_IN_OP(5); D = RM8(ea); break;                   /* LD   D,(IY+o)    */
+       case 0x5c: E = HY; break;                                               /* LD   E,HY        */
+       case 0x5d: E = LY; break;                                               /* LD   E,LY        */
+       case 0x5e: EAY(); CLOCK_IN_OP(5); E = RM8(ea); break;                   /* LD   E,(IY+o)    */
+       case 0x60: HY = B; break;                                               /* LD   HY,B        */
+       case 0x61: HY = C; break;                                               /* LD   HY,C        */
+       case 0x62: HY = D; break;                                               /* LD   HY,D        */
+       case 0x63: HY = E; break;                                               /* LD   HY,E        */
+       case 0x64: break;                                                       /* LD   HY,HY       */
+       case 0x65: HY = LY; break;                                              /* LD   HY,LY       */
+       case 0x66: EAY(); CLOCK_IN_OP(5); H = RM8(ea); break;                   /* LD   H,(IY+o)    */
+       case 0x67: HY = A; break;                                               /* LD   HY,A        */
+       case 0x68: LY = B; break;                                               /* LD   LY,B        */
+       case 0x69: LY = C; break;                                               /* LD   LY,C        */
+       case 0x6a: LY = D; break;                                               /* LD   LY,D        */
+       case 0x6b: LY = E; break;                                               /* LD   LY,E        */
+       case 0x6c: LY = HY; break;                                              /* LD   LY,HY       */
+       case 0x6d: break;                                                       /* LD   LY,LY       */
+       case 0x6e: EAY(); CLOCK_IN_OP(5); L = RM8(ea); break;                   /* LD   L,(IY+o)    */
+       case 0x6f: LY = A; break;                                               /* LD   LY,A        */
+       case 0x70: EAY(); CLOCK_IN_OP(5); WM8(ea, B); break;                    /* LD   (IY+o),B    */
+       case 0x71: EAY(); CLOCK_IN_OP(5); WM8(ea, C); break;                    /* LD   (IY+o),C    */
+       case 0x72: EAY(); CLOCK_IN_OP(5); WM8(ea, D); break;                    /* LD   (IY+o),D    */
+       case 0x73: EAY(); CLOCK_IN_OP(5); WM8(ea, E); break;                    /* LD   (IY+o),E    */
+       case 0x74: EAY(); CLOCK_IN_OP(5); WM8(ea, H); break;                    /* LD   (IY+o),H    */
+       case 0x75: EAY(); CLOCK_IN_OP(5); WM8(ea, L); break;                    /* LD   (IY+o),L    */
+       case 0x77: EAY(); CLOCK_IN_OP(5); WM8(ea, A); break;                    /* LD   (IY+o),A    */
+       case 0x7c: A = HY; break;                                               /* LD   A,HY        */
+       case 0x7d: A = LY; break;                                               /* LD   A,LY        */
+       case 0x7e: EAY(); CLOCK_IN_OP(5); A = RM8(ea); break;                   /* LD   A,(IY+o)    */
+       case 0x84: ADD(HY); break;                                              /* ADD  A,HY        */
+       case 0x85: ADD(LY); break;                                              /* ADD  A,LY        */
+       case 0x86: EAY(); CLOCK_IN_OP(5); ADD(RM8(ea)); break;                  /* ADD  A,(IY+o)    */
+       case 0x8c: ADC(HY); break;                                              /* ADC  A,HY        */
+       case 0x8d: ADC(LY); break;                                              /* ADC  A,LY        */
+       case 0x8e: EAY(); CLOCK_IN_OP(5); ADC(RM8(ea)); break;                  /* ADC  A,(IY+o)    */
+       case 0x94: SUB(HY); break;                                              /* SUB  HY          */
+       case 0x95: SUB(LY); break;                                              /* SUB  LY          */
+       case 0x96: EAY(); CLOCK_IN_OP(5); SUB(RM8(ea)); break;                  /* SUB  (IY+o)      */
+       case 0x9c: SBC(HY); break;                                              /* SBC  A,HY        */
+       case 0x9d: SBC(LY); break;                                              /* SBC  A,LY        */
+       case 0x9e: EAY(); CLOCK_IN_OP(5); SBC(RM8(ea)); break;                  /* SBC  A,(IY+o)    */
+       case 0xa4: AND(HY); break;                                              /* AND  HY          */
+       case 0xa5: AND(LY); break;                                              /* AND  LY          */
+       case 0xa6: EAY(); CLOCK_IN_OP(5); AND(RM8(ea)); break;                  /* AND  (IY+o)      */
+       case 0xac: XOR(HY); break;                                              /* XOR  HY          */
+       case 0xad: XOR(LY); break;                                              /* XOR  LY          */
+       case 0xae: EAY(); CLOCK_IN_OP(5); XOR(RM8(ea)); break;                  /* XOR  (IY+o)      */
+       case 0xb4: OR(HY); break;                                               /* OR   HY          */
+       case 0xb5: OR(LY); break;                                               /* OR   LY          */
+       case 0xb6: EAY(); CLOCK_IN_OP(5); OR(RM8(ea)); break;                   /* OR   (IY+o)      */
+       case 0xbc: CP(HY); break;                                               /* CP   HY          */
+       case 0xbd: CP(LY); break;                                               /* CP   LY          */
+       case 0xbe: EAY(); CLOCK_IN_OP(5); CP(RM8(ea)); break;                   /* CP   (IY+o)      */
+       case 0xcb: EAY(); v = FETCH8(); CLOCK_IN_OP(2); OP_XY(v); break;        /* **   FD CB xx    */
+       case 0xe1: POP(iy); break;                                              /* POP  IY          */
+       case 0xe3: EXSP(iy); break;                                             /* EX   (SP),IY     */
+       case 0xe5: PUSH(iy); break;                                             /* PUSH IY          */
+       case 0xe9: PC = IY; break;                                              /* JP   (IY)        */
+       case 0xf9: SP = IY; break;                                              /* LD   SP,IY       */
        default:   OP(code); break;
        }
 }
 
 void Z80::OP_ED(uint8_t code)
 {
+       // Done: M1 + M1
        icount -= cc_ed[code];
-       
+
        switch(code) {
        case 0x40: B = IN8(BC); F = (F & CF) | SZP[B]; break;                   /* IN   B,(C)       */
        case 0x41: OUT8(BC, B); break;                                          /* OUT  (C),B       */
@@ -1622,9 +1650,12 @@ void Z80::OP_ED(uint8_t code)
 
 void Z80::OP(uint8_t code)
 {
+       // Done: M1
+       uint8_t v;
+
        prevpc = PC - 1;
        icount -= cc_op[code];
-       
+
        switch(code) {
        case 0x00: break;                                                                                               /* NOP              */
        case 0x01: BC = FETCH16(); break;                                                                               /* LD   BC,w        */
@@ -1678,8 +1709,8 @@ void Z80::OP(uint8_t code)
        case 0x31: SP = FETCH16(); break;                                                                               /* LD   SP,w        */
        case 0x32: ea = FETCH16(); WM8(ea, A); WZ_L = (ea + 1) & 0xff; WZ_H = A; break;                                 /* LD   (w),A       */
        case 0x33: SP++; break;                                                                                         /* INC  SP          */
-       case 0x34: WM8(HL, INC(RM8(HL))); break;                                                                        /* INC  (HL)        */
-       case 0x35: WM8(HL, DEC(RM8(HL))); break;                                                                        /* DEC  (HL)        */
+       case 0x34: v = INC(RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;                                                 /* INC  (HL)        */
+       case 0x35: v = DEC(RM8(HL)); CLOCK_IN_OP(1); WM8(HL, v); break;                                                 /* DEC  (HL)        */
        case 0x36: WM8(HL, FETCH8()); break;                                                                            /* LD   (HL),n      */
        case 0x37: F = (F & (SF | ZF | YF | XF | PF)) | CF | (A & (YF | XF)); break;                                    /* SCF              */
        case 0x38: JR_COND(F & CF, 0x38); break;                                                                        /* JR   C,o         */
@@ -1827,7 +1858,6 @@ void Z80::OP(uint8_t code)
        case 0xc6: ADD(FETCH8()); break;                                                                                /* ADD  A,n         */
        case 0xc7: RST(0x00); break;                                                                                    /* RST  0           */
        case 0xc8: RET_COND(F & ZF, 0xc8); break;                                                                       /* RET  Z           */
-//#ifdef Z80_PSEUDO_BIOS
        case 0xc9:
                if(has_pseudo_bios) {
                        if(d_bios != NULL) {
@@ -1902,12 +1932,17 @@ void Z80::OP(uint8_t code)
 void Z80::initialize()
 {
        DEVICE::initialize();
+
+       waitfactor = 0;
+       waitcount = 0;
+       extra_cycles = 0;
+
        if(!flags_initialized) {
                uint8_t *padd = SZHVC_add;
                uint8_t *padc = SZHVC_add + 256 * 256;
                uint8_t *psub = SZHVC_sub;
                uint8_t *psbc = SZHVC_sub + 256 * 256;
-               
+
                for(int oldval = 0; oldval < 256; oldval++) {
                        for(int newval = 0; newval < 256; newval++) {
                                /* add or adc w/o carry set */
@@ -1918,7 +1953,7 @@ void Z80::initialize()
                                if(newval < oldval) *padd |= CF;
                                if((val ^ oldval ^ 0x80) & (val ^ newval) & 0x80) *padd |= VF;
                                padd++;
-                               
+
                                /* adc with carry set */
                                val = newval - oldval - 1;
                                *padc = (newval) ? ((newval & 0x80) ? SF : 0) : ZF;
@@ -1927,7 +1962,7 @@ void Z80::initialize()
                                if(newval <= oldval) *padc |= CF;
                                if((val ^ oldval ^ 0x80) & (val ^ newval) & 0x80) *padc |= VF;
                                padc++;
-                               
+
                                /* cp, sub or sbc w/o carry set */
                                val = oldval - newval;
                                *psub = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF);
@@ -1936,7 +1971,7 @@ void Z80::initialize()
                                if(newval > oldval) *psub |= CF;
                                if((val ^ oldval) & (oldval ^ newval) & 0x80) *psub |= VF;
                                psub++;
-                               
+
                                /* sbc with carry set */
                                val = oldval - newval - 1;
                                *psbc = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF);
@@ -2059,7 +2094,7 @@ void Z80::event_frame()
 
 }
 
-void Z80::reset()
+void Z80::special_reset(int num)
 {
        PCD = __CPU_START_ADDR;
        SPD = 0;
@@ -2070,15 +2105,21 @@ void Z80::reset()
        WZD = PCD;
        af2.d = bc2.d = de2.d = hl2.d = 0;
        ea = 0;
-       
+
        im = iff1 = iff2 = icr = 0;
-       after_halt = false;
-       after_ei = after_ldair = false;
+       after_halt = after_ei = false;
+       after_ldair = false;
        intr_req_bit = intr_pend_bit = 0;
-       
-       icount = extra_icount = busreq_icount = 0;
 }
-void __FASTCALL Z80::write_signal(int id, uint32_t data, uint32_t mask)
+
+void Z80::reset()
+{
+       special_reset(0);
+       icount = dma_icount = wait_icount = 0;
+       extra_cycles = 0;
+}
+
+void Z80::write_signal(int id, uint32_t data, uint32_t mask)
 {
        if(id == SIG_CPU_IRQ) {
                intr_req_bit = (intr_req_bit & ~mask) | (data & mask);
@@ -2091,6 +2132,10 @@ void __FASTCALL Z80::write_signal(int id, uint32_t data, uint32_t mask)
        } else if(id == SIG_CPU_BUSREQ) {
                busreq = ((data & mask) != 0);
                write_signals(&outputs_busack, busreq ? 0xffffffff : 0);
+       } else if(id == SIG_CPU_WAIT) {
+               wait = ((data & mask) != 0);
+       } else if(id == SIG_CPU_WAIT_FACTOR) {
+               waitfactor = data; // 65536.
        } else if(has_nsc800) {
 //#ifdef HAS_NSC800
                if(id == SIG_NSC800_INT) {
@@ -2110,7 +2155,7 @@ void __FASTCALL Z80::write_signal(int id, uint32_t data, uint32_t mask)
 //#endif
 }
 
-uint32_t __FASTCALL Z80::read_signal(int id)
+uint32_t  Z80::read_signal(int id)
 {
        if(id == SIG_CPU_IRQ) {
                return intr_req_bit;
@@ -2118,8 +2163,10 @@ uint32_t __FASTCALL Z80::read_signal(int id)
        return 0;
 }
 
-void __FASTCALL Z80::debugger_hook(void)
+// Maybe dummy.
+void  Z80::debugger_hook(void)
 {
+#if 0
 //#ifdef USE_DEBUGGER
        if((__USE_DEBUGGER) && (d_debugger != NULL)) {
                bool now_debugging = d_debugger->now_debugging;
@@ -2138,7 +2185,7 @@ void __FASTCALL Z80::debugger_hook(void)
                        } else {
                                now_debugging = false;
                        }
-               
+
                        //d_debugger->add_cpu_trace(PC);
                        int first_icount = icount;
                        //pPPC = pPC;
@@ -2151,176 +2198,196 @@ void __FASTCALL Z80::debugger_hook(void)
                }
        }
 //#endif
+#endif
 }
 
+void Z80:cpu_wait(int clocks)
+{
+       uint64_t ncount = 0;
+       if(clocks < 0) return;
+       if(waitfactor == 0) return;
+
+       waitcount += (waitfactor * (uint64_t)clocks);
+       const uint64_t _limit = (1 << (16 + 32 - 1)) - 1;
+       const int  _i_limit = (1 << (32 - 1)) - 1;
+       __UNLIKELY_IF(waitcount >= _limit) {
+               waitcount = _limit;
+       }
+       if(waitcount >= (1 << 16)) {
+               ncount = waitcount >> 16;
+               waitcount = waitcount - (ncount << 16);
+               __LIKELY_IF(ncount > 0) {
+                       extra_cycles += ncount;
+                       __UNLIKELY_IF(extra_cycles > _i_limit) {
+                               extra_cycles = _limit;
+                       }
+               }
+       }
+}
 
 int Z80::run(int clock)
 {
-
-       if(extra_icount > 0) {
-               extra_tmp_count += extra_icount;
-       }
+       bool __is_use_debugger =        ((__USE_DEBUGGER) && (d_debugger != nullptr)) ? true : false;
        if(clock == -1) {
                // this is primary cpu
-               if(busreq) {
+               if(wait) {
+                       // don't run cpu!
+                       if(__is_use_debugger) {
+                               total_icount += 1;
+                       }
+                       int tmp_extra_cycles = 0;
+                       if(extra_cycles > 0) {
+                               tmp_extra_cycles = extra_cycles;
+                       }
+                       extra_cycles = 0;
+                       cpu_wait(1);
+                       return tmp_extra_cycles + 1;
+               } else if(wait_icount > 0) {
+                       // don't run cpu!
+                       icount = wait_icount;
+                       wait_icount = 0;
+
+                       int tmp_extra_cycles = 0;
+                       if(extra_cycles > 0) {
+                               tmp_extra_cycles = extra_cycles;
+                       }
+                       extra_cycles = 0;
+                       if(__is_use_debugger) {
+                               total_icount += icount;
+                       }
+                       cpu_wait(icount);
+                       return icount + tmp_extra_cycles;
+               } else if(busreq || dma_icount > 0) {
                        // run dma once
-                       //#ifdef SINGLE_MODE_DMA
-                       if((d_dma != NULL)  && (has_single_mode_dma)) {
+                       if(has_single_mode_dma) {
+                               if(d_dma && dma_icount == 0) {
                                        d_dma->do_dma();
+                               }
                        }
-                       //#endif
+                       if(dma_icount > 0) {
+                               icount = dma_icount;
+                               dma_icount = 0;
+                       } else {
+                               icount = 1;
+                       }
+                       int tmp_extra_cycles = 0;
+                       if(extra_cycles > 0) {
+                               tmp_extra_cycles = extra_cycles;
+                       }
+                       extra_cycles = 0;
                        // don't run cpu!
-                       int passed_icount = max(1, extra_icount);
-                       // this is main cpu, icount is not used
-                       /*icount = */extra_icount = 0;
-                               total_icount += passed_icount;
-                               //#ifdef USE_DEBUGGER
-                               debugger_hook();
-                               //#endif
-                       return passed_icount;
+                       if(__is_use_debugger) {
+                               total_icount += icount;
+                       }
+                       cpu_wait(icount);
+                       return icount + tmp_extra_cycles;
                } else {
                        // run only one opcode
-                       if((extra_icount += busreq_icount) > 0) {
-                               if(is_primary) {
-                                       update_extra_event(extra_icount);
+                       icount = event_icount = event_done_icount = 0;
+                       run_one_opecode();
+                       if(wait || wait_icount > 0) {
+                               event_icount = (-icount) - (event_icount + event_done_icount);
+                               #ifdef _DEBUG
+                                       assert(event_icount >= 0);
+                               #endif
+                               if(event_icount > 0) wait_icount += event_icount;
+                       }
+                       if(__is_use_debugger) {
+                               total_icount += (-icount);
+                       }
+                       // run dma once
+                       if(has_single_mode_dma) {
+                               if(d_dma && dma_icount == 0 && !(wait || wait_icount > 0)) {
+                                       d_dma->do_dma();
                                }
-                               total_icount += extra_icount;
                        }
-                       icount = -extra_icount;
-                       extra_icount = busreq_icount = 0;
-                       run_one_opecode();
-                       insns_count++;
-                       return -icount;
+                       int tmp_extra_cycles = 0;
+                       if(extra_cycles > 0) {
+                               tmp_extra_cycles = extra_cycles;
+                       }
+                       extra_cycles = 0;
+                       cpu_wait(-icount);
+                       return (-icount) + tmp_extra_cycles;
                }
-       } else {
-               icount += clock;
+       } else if((icount += clock) > 0) {
+               // Secondary CPU or below.
                int first_icount = icount;
-               //#ifdef USE_DEBUGGER
-               total_icount += extra_icount;
-               //#endif
-               icount -= extra_icount;
-               extra_icount = 0;
-               
-               if(busreq) {
+               int tmp_icount;
+
+               if(busreq && !wait) {
+                       if(dma_icount > 0) {
+                               tmp_icount = min(icount, dma_icount);
+                               if(__is_use_debugger) {
+                                       total_icount += tmp_icount;
+                               }
+                               icount -= tmp_icount;
+                               dma_icount -= tmp_icount;
+                       }
                        // run dma once
-                       //#ifdef USE_DEBUGGER
-                       debugger_hook();
-                       //#endif
-                       //#ifdef SINGLE_MODE_DMA
-                       if((d_dma != NULL) && (has_single_mode_dma)) {
-                               d_dma->do_dma();
+                       if(has_single_mode_dma) {
+                               if(d_dma && dma_icount == 0) {
+                                       d_dma->do_dma();
+                               }
                        }
-                       //#endif
                } else {
-                       // run cpu while given clocks
-                       while(icount > 0 && !busreq) {
-                               run_one_opecode();
-                               insns_count++;
+                       // run cpu while given clocks remain
+                       while(icount > 0 && !(busreq || wait)) {
+                               if(dma_icount > 0) {
+                                       tmp_icount = min(icount, dma_icount);
+                                       if(__is_use_debugger) {
+                                               total_icount += tmp_icount;
+                                       }
+                                       icount -= tmp_icount;
+                                       dma_icount -= tmp_icount;
+                               } else {
+                                       // run only one opcode
+                                       if(__is_use_debugger) {
+                                               tmp_icount = icount;
+                                       }
+                                       run_one_opecode();
+                                       if(__is_use_debugger) {
+                                               total_icount += tmp_icount - icount;
+                                       }
+                                       // run dma once
+                                       if(has_single_mode_dma) {
+                                               if(d_dma && dma_icount == 0) {
+                                                       d_dma->do_dma();
+                                               }
+                                       }
+                               }
                        }
                }
-               // if busreq is raised, spin cpu while remained clock
-               if(icount > 0 && busreq) {
-                       //#ifdef USE_DEBUGGER
-                       total_icount += icount;
-                       //#endif
+               // spin cpu for remained clocks
+               if(icount > 0) {
+                       if(dma_icount > 0 && !wait) {
+                               dma_icount -= min(icount, dma_icount);
+                       }
+                       if(__is_use_debugger) {
+                               total_icount += icount;
+                       }
                        icount = 0;
                }
+               //cpu_wait(first_icount - icount);
                return first_icount - icount;
+       } else {
+               //int passed_icount = wait_icount;
+               //cpu_wait(1); // ToDo
+               return 0;
        }
 }
 
-
-void __FASTCALL Z80::run_one_opecode()
+void Z80::run_one_opecode()
 {
        // rune one opecode
-//#ifdef USE_DEBUGGER
+       bool prev_after_ei = after_ei;
+
+       after_halt = after_ei = false;
+       after_ldair = false;
+
        bool now_debugging = false;
-       if((__USE_DEBUGGER) && (d_debugger != NULL)) {
-               now_debugging = d_debugger->now_debugging;
-       }
-       if(now_debugging) {
-               d_debugger->check_break_points(PC);
-               if(d_debugger->now_suspended) {
-                       d_debugger->now_waiting = true;
-                       emu->start_waiting_in_debugger();
-                       while(d_debugger->now_debugging && d_debugger->now_suspended) {
-                               emu->process_waiting_in_debugger();
-                       }
-                       emu->finish_waiting_in_debugger();
-                       d_debugger->now_waiting = false;
-               }
-               if(d_debugger->now_debugging) {
-                       d_mem = d_io = d_debugger;
-               } else {
-                       now_debugging = false;
-               }
-               
-               after_halt = after_ei = false;
-//#if HAS_LDAIR_QUIRK
-               if(has_ldair_quirk) {
-                       after_ldair = false;
-               }
-//#endif
-               OP(FETCHOP());
-//#if HAS_LDAIR_QUIRK
-               if((has_ldair_quirk) && (after_ldair)) {
-                       F &= ~PF;       // reset parity flag after LD A,I or LD A,R
-               }
-//#endif
-//#ifdef SINGLE_MODE_DMA
-               if((d_dma != NULL) && (has_single_mode_dma)) {
-                       d_dma->do_dma();
-               }
-//#endif
-               if(!after_ei) {
-                       check_interrupt();
-               }
-               
-               if(now_debugging) {
-                       if(!d_debugger->now_going) {
-                               d_debugger->now_suspended = true;
-                       }
-                       d_mem = d_mem_stored;
-                       d_io = d_io_stored;
-               }
-       } else {
-//#endif
-               after_halt = after_ei = false;
-//#if HAS_LDAIR_QUIRK
-               if(has_ldair_quirk) {
-                       after_ldair = false;
-               }
-//#endif
-               d_debugger->add_cpu_trace(PC);
-               int first_icount = icount;
-               OP(FETCHOP());
-               icount -= extra_icount;
-               extra_icount = 0;
-               total_icount += first_icount - icount;
-//#if HAS_LDAIR_QUIRK
-               if((has_ldair_quirk) && (after_ldair)) {
-                       F &= ~PF;       // reset parity flag after LD A,I or LD A,R
-               }
-//#endif
-//#ifdef SINGLE_MODE_DMA
-               if((d_dma != NULL) && (has_single_mode_dma)) {
-                       d_dma->do_dma();
-               }
-//#endif
-               if(!after_ei) {
-                       check_interrupt();
-               }
 //#ifdef USE_DEBUGGER
-       }
-//#endif
-       
-       // ei: run next opecode
-       now_debugging = false;
-       if(after_ei) {
-//#ifdef USE_DEBUGGER
-               if((__USE_DEBUGGER) && (d_debugger != NULL)) {
-                       now_debugging = d_debugger->now_debugging;
-               }
+       if((__USE_DEBUGGER) && (d_debugger != nullptr)) {
+               now_debugging = d_debugger->now_debugging;
                if(now_debugging) {
                        d_debugger->check_break_points(PC);
                        if(d_debugger->now_suspended) {
@@ -2337,27 +2404,22 @@ void __FASTCALL Z80::run_one_opecode()
                        } else {
                                now_debugging = false;
                        }
-                       
-                       after_halt = false;
-//#if HAS_LDAIR_QUIRK
-               if(has_ldair_quirk) {
-                       after_ldair = false;
-               }
-//#endif
+                       d_debugger->add_cpu_trace(PC);
                        OP(FETCHOP());
 //#if HAS_LDAIR_QUIRK
-                       if((has_ldair_quirk) && (after_ldair)) {
-                               F &= ~PF;       // reset parity flag after LD A,I or LD A,R
+                       if(has_ldair_quirk) {
+                               if(after_ldair) {
+                                       F &= ~PF;       // reset parity flag after LD A,I or LD A,R
+                               }
                        }
 //#endif
-//#ifdef SINGLE_MODE_DMA
-                       if((d_dma != NULL) && (has_single_mode_dma)) {
-                               d_dma->do_dma();
+                       if(prev_after_ei) {
+                               d_pic->notify_intr_ei();
+                               check_interrupt();
+                               after_ei = false;
+                       } else if(!after_ei) {
+                               check_interrupt();
                        }
-//#endif
-                       if(d_pic != NULL) d_pic->notify_intr_ei();
-                       check_interrupt();
-                       
                        if(now_debugging) {
                                if(!d_debugger->now_going) {
                                        d_debugger->now_suspended = true;
@@ -2365,49 +2427,34 @@ void __FASTCALL Z80::run_one_opecode()
                                d_mem = d_mem_stored;
                                d_io = d_io_stored;
                        }
+                       return;
                } else {
-//#endif
-                       after_halt = false;
-//#if HAS_LDAIR_QUIRK
-                       if(has_ldair_quirk) {
-                               after_ldair = false;
-                       }
-//#endif
                        d_debugger->add_cpu_trace(PC);
-                       int first_icount = icount;
-                       OP(FETCHOP());
-                       icount -= extra_icount;
-                       extra_icount = 0;
-                       total_icount += first_icount - icount;
-//#if HAS_LDAIR_QUIRK
-                       if((has_ldair_quirk) &&(after_ldair)) {
-                               F &= ~PF;       // reset parity flag after LD A,I or LD A,R
-                       }
-//#endif
-//#ifdef SINGLE_MODE_DMA
-                       if((d_dma != NULL) && (has_single_mode_dma)) {
-                               d_dma->do_dma();
-                       }
-//#endif
-                       if(d_pic != NULL) d_pic->notify_intr_ei();
-                       check_interrupt();
-//#ifdef USE_DEBUGGER
                }
+       }
 //#endif
+       OP(FETCHOP());
+//#if HAS_LDAIR_QUIRK
+       if(has_ldair_quirk) {
+               if(after_ldair) {
+                       F &= ~PF;       // reset parity flag after LD A,I or LD A,R
+               }
        }
-//#ifndef USE_DEBUGGER
-       if(!(__USE_DEBUGGER)) { // OK?
-               icount -= extra_icount;
-               extra_icount = 0;
+//#endif
+       if(prev_after_ei) {
+               d_pic->notify_intr_ei();
+               check_interrupt();
+               after_ei = false;
+       } else if(!after_ei) {
+               check_interrupt();
        }
+//#ifdef USE_DEBUGGER
+//}
 //#endif
 }
 
 void Z80::check_interrupt()
 {
-//#ifdef USE_DEBUGGER
-       int first_icount = icount;
-//#endif
        // check interrupt
        if(intr_req_bit) {
                if(intr_req_bit & NMI_REQ_BIT) {
@@ -2461,7 +2508,7 @@ void Z80::check_interrupt()
                        if(iff1) {
                                // interrupt
                                LEAVE_HALT();
-                               
+
                                uint32_t vector = 0xcd;
                                if(d_pic != NULL) vector = d_pic->get_intr_ack();
                                if(im == 0) {
@@ -2501,31 +2548,28 @@ void Z80::check_interrupt()
 //#else
                }
        }
-//#ifdef USE_DEBUGGER
-       total_icount += first_icount - icount;
-//#endif
 }
 
 //#ifdef USE_DEBUGGER
-void __FASTCALL Z80::write_debug_data8(uint32_t addr, uint32_t data)
+void  Z80::write_debug_data8(uint32_t addr, uint32_t data)
 {
        int wait;
        d_mem_stored->write_data8w(addr, data, &wait);
 }
 
-uint32_t __FASTCALL Z80::read_debug_data8(uint32_t addr)
+uint32_t  Z80::read_debug_data8(uint32_t addr)
 {
        int wait;
        return d_mem_stored->read_data8w(addr, &wait);
 }
 
-void __FASTCALL Z80::write_debug_io8(uint32_t addr, uint32_t data)
+void  Z80::write_debug_io8(uint32_t addr, uint32_t data)
 {
        int wait;
        d_io_stored->write_io8w(addr, data, &wait);
 }
 
-uint32_t __FASTCALL Z80::read_debug_io8(uint32_t addr)
+uint32_t  Z80::read_debug_io8(uint32_t addr)
 {
        int wait;
        return d_io_stored->read_io8w(addr, &wait);
@@ -2683,7 +2727,7 @@ int z80_dasm_main(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *firs
        buffer[0] = _T('\0');
        z80_dasm_ptr = 0;
        uint8_t code = dasm_fetchop();
-       
+
        switch(code) {
        case 0x00: my_stprintf_s(buffer, buffer_len, _T("NOP")); break;
        case 0x01: my_stprintf_s(buffer, buffer_len, _T("LD BC, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break;
@@ -2951,7 +2995,7 @@ int z80_dasm_main(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *firs
 static void dasm_cb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol)
 {
        uint8_t code = dasm_fetchop();
-       
+
        switch(code) {
        case 0x00: my_stprintf_s(buffer, buffer_len, _T("RLC B")); break;
        case 0x01: my_stprintf_s(buffer, buffer_len, _T("RLC C")); break;
@@ -3219,7 +3263,7 @@ static void dasm_dd(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *fi
 {
        uint8_t code = dasm_fetchop();
        int8_t ofs;
-       
+
        switch(code) {
        case 0x09: my_stprintf_s(buffer, buffer_len, _T("ADD IX, BC")); break;
        case 0x19: my_stprintf_s(buffer, buffer_len, _T("ADD IX, DE")); break;
@@ -3314,7 +3358,7 @@ static void dasm_dd(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *fi
 void dasm_ed(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol)
 {
        uint8_t code = dasm_fetchop();
-       
+
        switch(code) {
        case 0x40: my_stprintf_s(buffer, buffer_len, _T("IN B, (C)")); break;
        case 0x41: my_stprintf_s(buffer, buffer_len, _T("OUT (C), B")); break;
@@ -3402,7 +3446,7 @@ void dasm_fd(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_sym
 {
        uint8_t code = dasm_fetchop();
        int8_t ofs;
-       
+
        switch(code) {
        case 0x09: my_stprintf_s(buffer, buffer_len, _T("ADD IY, BC")); break;
        case 0x19: my_stprintf_s(buffer, buffer_len, _T("ADD IY, DE")); break;
@@ -3498,7 +3542,7 @@ static void dasm_ddcb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *
 {
        int8_t ofs = debug_fetch8_rel();
        uint8_t code = debug_fetch8();
-       
+
        switch(code) {
        case 0x00: my_stprintf_s(buffer, buffer_len, _T("RLC B=(IX+(%d))"), ofs); break;
        case 0x01: my_stprintf_s(buffer, buffer_len, _T("RLC C=(IX+(%d))"), ofs); break;
@@ -3766,7 +3810,7 @@ static void dasm_fdcb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *
 {
        int8_t ofs = debug_fetch8_rel();
        uint8_t code = debug_fetch8();
-       
+
        switch(code) {
        case 0x00: my_stprintf_s(buffer, buffer_len, _T("RLC B=(IY+(%d))"), ofs); break;
        case 0x01: my_stprintf_s(buffer, buffer_len, _T("RLC C=(IY+(%d))"), ofs); break;
@@ -4031,7 +4075,7 @@ static void dasm_fdcb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *
 }
 
 } // extern "C"
+
 int Z80::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata )
 {
        for(int i = 0; i < 4; i++) {
@@ -4041,7 +4085,7 @@ int Z80::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len
        return z80_dasm_main(pc, buffer, buffer_len, d_debugger->first_symbol);
 }
 
-#define STATE_VERSION 4
+#define STATE_VERSION 5
 
 bool Z80::process_state(FILEIO* state_fio, bool loading)
 {
@@ -4053,10 +4097,10 @@ bool Z80::process_state(FILEIO* state_fio, bool loading)
                return false;
        }
        state_fio->StateValue(total_icount);
-       
+
        state_fio->StateValue(icount);
-       state_fio->StateValue(extra_icount);
-       state_fio->StateValue(busreq_icount);
+       state_fio->StateValue(dma_icount);
+       state_fio->StateValue(wait_icount);
        state_fio->StateValue(prevpc);
        state_fio->StateValue(pc.d);
        state_fio->StateValue(sp.d);
@@ -4076,6 +4120,7 @@ bool Z80::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(R2);
        state_fio->StateValue(ea);
        state_fio->StateValue(busreq);
+       state_fio->StateValue(wait);
        state_fio->StateValue(after_halt);
        state_fio->StateValue(im);
        state_fio->StateValue(iff1);
@@ -4085,7 +4130,10 @@ bool Z80::process_state(FILEIO* state_fio, bool loading)
        state_fio->StateValue(after_ldair);
        state_fio->StateValue(intr_req_bit);
        state_fio->StateValue(intr_pend_bit);
-       
+       state_fio->StateValue(waitfactor);
+       state_fio->StateValue(waitcount);
+       state_fio->StateValue(extra_cycles);
+
        // post process
        if(loading) {
                prev_total_icount = total_icount;
@@ -4106,4 +4154,3 @@ bool Z80::process_state(FILEIO* state_fio, bool loading)
 
 
 //#endif
-
index b6ece69..8bdd38c 100644 (file)
@@ -8,7 +8,7 @@
        [ Z80 ]
 */
 
-#ifndef _Z80_H_ 
+#ifndef _Z80_H_
 #define _Z80_H_
 
 #include "device.h"
@@ -33,7 +33,7 @@ protected:
        /* ---------------------------------------------------------------------------
        contexts
        --------------------------------------------------------------------------- */
-       
+
        DEVICE *d_mem, *d_io, *d_pic;
 //#ifdef Z80_PSEUDO_BIOS
        DEVICE *d_bios;
@@ -56,29 +56,31 @@ protected:
        bool has_ldair_quirk;
        bool has_single_mode_dma;
        bool flags_initialized;
-       
+
        bool is_primary;
-       
+
+       uint64_t waitfactor;
+       uint64_t waitcount;
        /* ---------------------------------------------------------------------------
        registers
        --------------------------------------------------------------------------- */
-       
+
        uint64_t total_icount;
        uint64_t prev_total_icount;
-       int icount;
-       int extra_icount;
-       int busreq_icount;
+       int64_t icount;
+       int64_t dma_icount;
+       int64_t wait_icount, event_icount, event_done_icount;
        uint16_t prevpc;
        pair32_t pc, sp, af, bc, de, hl, ix, iy, wz;
        pair32_t af2, bc2, de2, hl2;
        uint8_t I, R, R2;
        uint32_t ea;
-       
-       bool busreq, after_halt;
+
+       bool busreq, wait, after_halt;
        uint8_t im, iff1, iff2, icr;
        bool after_ei, after_ldair;
        uint32_t intr_req_bit, intr_pend_bit;
-       
+
        Z80_INLINE uint8_t __FASTCALL RM8(uint32_t addr);
        Z80_INLINE void __FASTCALL WM8(uint32_t addr, uint8_t val);
        Z80_INLINE void __FASTCALL RM16(uint32_t addr, pair32_t *r);
@@ -88,10 +90,10 @@ protected:
        Z80_INLINE uint32_t __FASTCALL FETCH16();
        Z80_INLINE uint8_t __FASTCALL IN8(uint32_t addr);
        Z80_INLINE void __FASTCALL OUT8(uint32_t addr, uint8_t val);
-       
+
        Z80_INLINE uint8_t __FASTCALL INC(uint8_t value);
        Z80_INLINE uint8_t __FASTCALL DEC(uint8_t value);
-       
+
        Z80_INLINE uint8_t __FASTCALL RLC(uint8_t value);
        Z80_INLINE uint8_t __FASTCALL RRC(uint8_t value);
        Z80_INLINE uint8_t __FASTCALL RL(uint8_t value);
@@ -100,19 +102,20 @@ protected:
        Z80_INLINE uint8_t __FASTCALL SRA(uint8_t value);
        Z80_INLINE uint8_t __FASTCALL SLL(uint8_t value);
        Z80_INLINE uint8_t __FASTCALL SRL(uint8_t value);
-       
+
        Z80_INLINE uint8_t __FASTCALL RES(uint8_t bit, uint8_t value);
        Z80_INLINE uint8_t __FASTCALL SET(uint8_t bit, uint8_t value);
-       
-       void OP_CB(uint8_t code);
-       void OP_XY(uint8_t code);
-       void OP_DD(uint8_t code);
-       void OP_FD(uint8_t code);
-       void OP_ED(uint8_t code);
-       void OP(uint8_t code);
-       virtual void __FASTCALL run_one_opecode();
-       virtual void __FASTCALL debugger_hook(void);
-       
+
+       void __FASTCALL OP_CB(uint8_t code);
+       void __FASTCALL OP_XY(uint8_t code);
+       void __FASTCALL OP_DD(uint8_t code);
+       void __FASTCALL OP_FD(uint8_t code);
+       void __FASTCALL OP_ED(uint8_t code);
+       void __FASTCALL OP(uint8_t code);
+       virtual void run_one_opecode();
+       virtual void debugger_hook(void);
+       virtual void __FASTCALL cpu_wait(int clocks);
+
        uint8_t SZ[256];                /* zero and sign flags */
        uint8_t SZ_BIT[256];    /* zero, sign and parity/overflow (=zero) flags for BIT opcode */
        uint8_t SZP[256];               /* zero, sign and parity flags */
@@ -159,7 +162,7 @@ protected:
                8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8,
                8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8
        };
-       
+
         const uint8_t cc_ed[0x100] = {
                8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
                8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
@@ -178,7 +181,7 @@ protected:
                8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
                8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
        };
-       
+
         const uint8_t cc_xy[0x100] = {
                4, 4, 4, 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4,
                4, 4, 4, 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4,
@@ -216,7 +219,7 @@ protected:
                23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
                23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23
        };
-       
+
        const uint8_t cc_ex[0x100] = {
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DJNZ */
@@ -257,7 +260,7 @@ public:
        Z80(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu)
        {
                flags_initialized = false;
-               busreq = false;
+               busreq = wait = false;
 //#ifdef Z80_PSEUDO_BIOS
                d_bios = NULL;
 //#endif
@@ -281,71 +284,72 @@ public:
 
        }
        ~Z80() {}
-       
+
        // common functions
-       virtual void initialize();
-       virtual void reset();
-       void event_frame();
-       int __FASTCALL run(int clock);
-
-       virtual bool process_state(FILEIO* state_fio, bool loading);
-       
-       void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask);
-       uint32_t __FASTCALL read_signal(int id);
-       
-       void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit)
+       virtual void initialize() override;
+       virtual void reset() override;
+       virtual void special_reset(int num) override;
+       void event_frame() override;
+       int __FASTCALL run(int clock) override;
+
+       virtual bool process_state(FILEIO* state_fio, bool loading) override;
+
+       void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask) override;
+       uint32_t __FASTCALL read_signal(int id) override;
+
+       void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit) override
        {
                uint32_t mask = 1 << bit;
                intr_req_bit = line ? (intr_req_bit | mask) : (intr_req_bit & ~mask);
                intr_pend_bit = pending ? (intr_pend_bit | mask) : (intr_pend_bit & ~mask);
                if(line) irq_count++;
        }
-       void __FASTCALL set_extra_clock(int clock)
+       void __FASTCALL set_extra_clock(int clock) override
        {
-               extra_icount += clock;
+               dma_icount += clock;
        }
-       int get_extra_clock()
+       int get_extra_clock() override
        {
-               return extra_icount;
+               return dma_icount;
        }
-       uint32_t get_pc()
+       uint32_t get_pc() override
        {
                return prevpc;
        }
-       uint32_t get_next_pc()
+       uint32_t get_next_pc() override
        {
                return pc.w.l;
        }
 //#ifdef USE_DEBUGGER
-       bool is_cpu()
+       bool is_cpu() override
        {
                return true;
        }
-       bool is_debugger_available()
+       bool is_debugger_available() override
        {
                return true;
        }
-       void *get_debugger()
+       void *get_debugger() override
        {
                return d_debugger;
        }
-       uint32_t get_debug_prog_addr_mask()
+       uint32_t get_debug_prog_addr_mask() override
        {
                return 0xffff;
        }
-       uint32_t get_debug_data_addr_mask()
+       uint32_t get_debug_data_addr_mask() override
        {
                return 0xffff;
        }
-       
-       void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data);
-       uint32_t __FASTCALL read_debug_data8(uint32_t addr);
-       void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data);
-       uint32_t __FASTCALL read_debug_io8(uint32_t addr);
-       
-       bool write_debug_reg(const _TCHAR *reg, uint32_t data);
-       bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len);
-       virtual int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0);
+
+       void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data) override;
+       uint32_t __FASTCALL read_debug_data8(uint32_t addr) override;
+       void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data) override;
+       uint32_t __FASTCALL read_debug_io8(uint32_t addr) override;
+
+       bool write_debug_reg(const _TCHAR *reg, uint32_t data) override;
+       bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) override;
+       virtual int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0) override;
 //#endif
        // unique functions
        void set_context_mem(DEVICE* device)
@@ -392,4 +396,3 @@ public:
 
 
 #endif
-