OSDN Git Service

[Qt][DEBUGGER] Temporally revert changes around debugger, will use src/debugger.cpp .
authorK.Ohta <whatisthis.sowhat@gmail.com>
Mon, 21 Dec 2015 10:40:55 +0000 (19:40 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Mon, 21 Dec 2015 10:40:55 +0000 (19:40 +0900)
13 files changed:
source/src/CMakeLists.txt
source/src/debugger.cpp
source/src/emu.h
source/src/qt/common/emu_thread.cpp
source/src/qt/common/emu_thread.h
source/src/qt/common/emuevents_control.cpp
source/src/qt/debugger/CMakeLists.txt
source/src/qt/debugger/debugger_thread.cpp [new file with mode: 0644]
source/src/qt/debugger/qt_debugger.cpp
source/src/qt/debugger/qt_debugger.h
source/src/qt/osd.cpp
source/src/qt/osd.h
source/src/qt/osd_console.cpp

index bc1b184..3d2d85a 100644 (file)
@@ -8,7 +8,7 @@ add_library(common_common
 #        emu.cpp
          fifo.cpp
          fileio.cpp
-         debugger.cpp
+#        debugger.cpp
 )
 
 add_library(common_emu
index 4edbc99..d833b12 100644 (file)
@@ -18,6 +18,9 @@
 #include "vm/debugger.h"
 #include "vm/vm.h"
 #include "fileio.h"
+#if defined(OSD_QT)
+#include "emu_thread.h"
+#endif
 
 #ifdef USE_DEBUGGER
 
@@ -48,7 +51,7 @@ void my_printf(OSD *osd, const _TCHAR *format, ...)
        if(logfile != NULL && logfile->IsOpened()) {
                logfile->Fwrite(buffer, lstrlen(buffer) * sizeof(_TCHAR), 1);
        }
-#else   
+#else  
        if(logfile != NULL && logfile->IsOpened()) {
                logfile->Fwrite(buffer, strlen(buffer) * sizeof(_TCHAR), 1);
        }
@@ -124,7 +127,7 @@ break_point_t *get_break_point(DEBUGGER *debugger, const _TCHAR *command)
 }
 
 
-static int debugger_command(debugger_thread_t *p, _TCHAR *command, _TCHAR *prev_command, bool cp932)
+int debugger_command(debugger_thread_t *p, _TCHAR *command, _TCHAR *prev_command, bool cp932)
 {
        DEVICE *cpu = p->vm->get_cpu(p->cpu_index);
        DEBUGGER *debugger = (DEBUGGER *)cpu->get_debugger();
@@ -132,6 +135,9 @@ static int debugger_command(debugger_thread_t *p, _TCHAR *command, _TCHAR *prev_
        uint32 data_addr_mask = cpu->debug_data_addr_mask();
        uint32 dump_addr = 0;
        uint32 dasm_addr = cpu->get_next_pc();
+       //while(!debugger->now_suspended) {
+       //              p->osd->sleep(10);
+       //}
        
        // initialize console
        _TCHAR buffer[1024];
@@ -581,6 +587,14 @@ static int debugger_command(debugger_thread_t *p, _TCHAR *command, _TCHAR *prev_
                                                }
                                                p->osd->sleep(10);
                                        }
+#elif defined(OSD_QT)
+                                       while(!p->request_terminate && !debugger->now_suspended) {
+                                               if(p->osd->console_input_string() != NULL && p->osd->is_console_active()) {
+                                                       p->osd->clear_console_input_string();
+                                                       break;
+                                               }
+                                               p->osd->sleep(10);
+                                       }
 #endif                                    
                                        // break cpu
                                        debugger->now_going = false;
@@ -650,6 +664,11 @@ static int debugger_command(debugger_thread_t *p, _TCHAR *command, _TCHAR *prev_
                                                if(debugger->hit() || ((GetAsyncKeyState(VK_ESCAPE) & 0x8000) != 0 && p->osd->is_console_active())) {
                                                        break;
                                                }
+#elif defined(OSD_QT)
+                                               if(debugger->hit() || p->osd->console_input_string() != NULL && p->osd->is_console_active()) {
+                                                       p->osd->clear_console_input_string();
+                                                       break;
+                                               }
 #endif                                    
                                        }
                                        if(debugger->hit()) {
@@ -824,7 +843,6 @@ int debugger_thread(void *lpx)
        _TCHAR prev_command[MAX_COMMAND_LEN + 1];
        
        memset(prev_command, 0, sizeof(prev_command));
-       
        while(!p->request_terminate) {
                my_printf(p->osd, _T("- "));
                
@@ -921,12 +939,56 @@ void EMU::open_debugger(int cpu_index)
                        debugger_thread_param.request_terminate = false;
 #ifdef _WIN32
                        if((hDebuggerThread = (HANDLE)_beginthreadex(NULL, 0, debugger_thread, &debugger_thread_param, 0, NULL)) != (HANDLE)0) {
-#else
+#elif !defined(_USE_QT)
                        if((debugger_thread_id = SDL_CreateThread(debugger_thread, "DebuggerThread", (void *)&debugger_thread_param)) != 0) {
+#else // USE_QT
+                               {
+                                       volatile debugger_thread_t *p = (debugger_thread_t *)(&debugger_thread_param);
+                                       p->running = true;
+                                       
+                                       DEVICE *cpu = p->vm->get_cpu(p->cpu_index);
+                                       DEBUGGER *debugger = (DEBUGGER *)cpu->get_debugger();
+                                       
+                                       debugger->now_going = false;
+                                       debugger->now_debugging = true;
+                                       //while(!debugger->now_suspended) {
+                                       //      p->osd->sleep(10);
+                                       //}
+                                       
+                                       uint32 prog_addr_mask = cpu->debug_prog_addr_mask();
+                                       uint32 data_addr_mask = cpu->debug_data_addr_mask();
+                                       uint32 dump_addr = 0;
+                                       uint32 dasm_addr = cpu->get_next_pc();
+       
+                                       // initialize console
+                                       _TCHAR buffer[1024];
+                                       my_stprintf_s(buffer, 1024, _T("Debugger - %s"), _T(DEVICE_NAME));
+                                       
+                                       p->osd->open_console(buffer);
+                                       
+                                       bool cp932 = (p->osd->get_console_code_page() == 932);
+                                       
+                                       p->osd->set_console_text_attribute(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+                                       cpu->debug_regs_info(buffer, 1024);
+                                       my_printf(p->osd, _T("%s\n"), buffer);
+                                       
+                                       p->osd->set_console_text_attribute(FOREGROUND_RED | FOREGROUND_INTENSITY);
+                                       my_printf(p->osd, _T("breaked at %08X\n"), cpu->get_next_pc());
+                                       
+                                       p->osd->set_console_text_attribute(FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+                                       cpu->debug_dasm(cpu->get_next_pc(), buffer, 1024);
+                                       my_printf(p->osd, _T("next\t%08X  %s\n"), cpu->get_next_pc(), buffer);
+                                       p->osd->set_console_text_attribute(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+       
+                                       // initialize logfile
+                                       if(logfile != NULL && logfile->IsOpened()) {
+                                               logfile->Fclose();
+                                       }
+                                       logfile = NULL;
 #endif
-                               stop_rec_sound();
-                               stop_rec_video();
-                               now_debugging = true;
+                                       stop_rec_sound();
+                                       stop_rec_video();
+                                       now_debugging = true;
                        }
                }
        }
@@ -941,9 +1003,19 @@ void EMU::close_debugger()
 #ifdef _WIN32
                WaitForSingleObject(hDebuggerThread, INFINITE);
                CloseHandle(hDebuggerThread);
-#else
+#elif !defined(_USE_QT)
                //pthread_join(debugger_thread_id, NULL);
                SDL_DetachThread(debugger_thread_id);
+#else
+               volatile debugger_thread_t *p = (debugger_thread_t *)(&debugger_thread_param);
+               p->running = false;
+               
+               if(logfile != NULL && logfile->IsOpened()) {
+                       logfile->Fclose();
+               }
+               // initialize logfile
+               logfile = NULL;
+               
 #endif
                now_debugging = false;
        }
index 95f72b9..2d3f1a0 100644 (file)
@@ -191,6 +191,10 @@ public:
        {
                return vm;
        }
+       OSD *get_osd()
+       {
+               return osd;
+       }
        void set_host_cpus(int v);
        int get_host_cpus();
 #endif
index e9180c4..31eccb0 100644 (file)
@@ -487,7 +487,8 @@ void EmuThreadClass::doWork(const QString &params)
        bool horiz_line_bak = config.opengl_scanline_horiz;
        bool gl_crt_filter_bak = config.use_opengl_filters;
        int opengl_filter_num_bak = config.opengl_filter_num;
-       int no_draw_count = 0;
+       int no_draw_count = 0;  
+       doing_debug_command = false;
        
        ctext.clear();
        draw_timing = false;
@@ -694,4 +695,48 @@ void EmuThreadClass::doSaveState()
 {
        bSaveStateReq = true;
 }
+// Debugger
+#if defined(USE_DEBUGGER)
+extern int debugger_command(debugger_thread_t *p, _TCHAR *command, _TCHAR *prev_command, bool cp932);
+#endif
+void EmuThreadClass::do_call_debugger_command(QString s)
+{
+#if 0   
+#if defined(USE_DEBUGGER)
+       _TCHAR command[MAX_COMMAND_LEN + 1];
+
+       if(doing_debug_command) {
+               emit sig_debugger_input(s);
+               return;
+       }
+       memset(command, 0x00, MAX_COMMAND_LEN + 1);
+       if(s.isEmpty()) {
+               strncpy(command, dbg_prev_command, MAX_COMMAND_LEN);
+       } else {
+               strncpy(command, s.toUtf8().constData(), MAX_COMMAND_LEN);
+       }
+       doing_debug_command = true;
+       if(debugger_command(&(p_emu->debugger_thread_param), command, dbg_prev_command, false) < 0) {
+               do_close_debugger();
+       }
+       doing_debug_command = false;
+#endif
+#endif   
+}
 
+void EmuThreadClass::do_close_debugger(void)
+{
+#if 0   
+#if defined(USE_DEBUGGER)
+       emit sig_quit_debugger();
+#endif
+#endif
+}
+
+bool EmuThreadClass::now_debugging() {
+#if defined(USE_DEBUGGER)
+       return p_emu->now_debugging;
+#else
+       return false;
+#endif
+}
index 6715e9d..7b55f1c 100644 (file)
@@ -31,6 +31,7 @@ class QWaitCondition;
 #endif
 
 QT_BEGIN_NAMESPACE
+#define MAX_COMMAND_LEN        64
 
 class EmuThreadClass : public QThread {
        Q_OBJECT
@@ -40,7 +41,10 @@ private:
        bool tape_rec_flag;
        int tape_pos;
        bool mouse_flag;
+       char dbg_prev_command[MAX_COMMAND_LEN];
+
        int get_interval(void);
+       
  protected:
        EMU *p_emu;
        QWaitCondition *drawCond;
@@ -54,6 +58,7 @@ private:
        bool bStartRecordSoundReq;
        bool bStopRecordSoundReq;
        bool draw_timing;
+       bool doing_debug_command;
        
        uint32 next_time;
        uint32 update_fps_time;
@@ -84,6 +89,7 @@ public:
        void run() { doWork("");}
        EmuThreadClass *currentHandler();
        void resize_screen(int sw, int sh, int stw, int sth);
+       bool now_debugging();
 public slots:
        void doWork(const QString &param);
        void doExit(void);
@@ -139,6 +145,9 @@ public slots:
        void do_start_auto_key(QString text);
        void do_stop_auto_key(void);
        void do_draw_timing(bool);
+       void do_call_debugger_command(QString s);
+       void do_close_debugger(void);
+       
 signals:
        int message_changed(QString);
        int sig_draw_thread(bool);
@@ -170,6 +179,8 @@ signals:
        int sig_resize_screen(int, int);
        int sig_resize_uibar(int, int);
        int sig_auto_key_string(QByteArray);
+       int sig_debugger_input(QString);
+       int sig_quit_debugger();
 };
 
 QT_END_NAMESPACE
index 1ed922f..324bfb5 100644 (file)
@@ -65,24 +65,46 @@ void Ui_MainWindow::OnStopAutoKey(void)
 void Ui_MainWindow::OnOpenDebugger(int no)
 {
        if((no < 0) || (no > 3)) return;
-
-       if(emu->now_debugging)  this->OnCloseDebugger();
-       emu->open_debugger(no);
-       OSD *p_osd = emu->debugger_thread_param.osd;
-       emu->hDebugger = new CSP_Debugger(this, p_osd);
-       connect(p_osd, SIGNAL(sig_put_string_debugger(QString)), emu->hDebugger, SLOT(put_string(QString)), Qt::DirectConnection);
-       emu->hDebugger->show();
-       emu->hDebugger->run();
+       //emu->open_debugger(no);
+       VM *vm = emu->get_vm();
+
+       if(emu->now_debugging)  this->OnCloseDebugger();
+       if(!(emu->now_debugging && emu->debugger_thread_param.cpu_index == no)) {
+               //emu->close_debugger();
+               if(vm->get_cpu(no) != NULL && vm->get_cpu(no)->get_debugger() != NULL) {
+                       
+                       emu->hDebugger = new CSP_Debugger(this);
+                       QString objNameStr = QString("EmuDebugThread");
+                       emu->hDebugger->setObjectName(objNameStr);
+                       emu->hDebugger->debugger_thread_param.osd = emu->get_osd();
+                       emu->hDebugger->debugger_thread_param.vm = vm;
+                       emu->hDebugger->debugger_thread_param.cpu_index = no;
+                       emu->stop_rec_sound();
+                       emu->stop_rec_video();
+                       emu->now_debugging = true;
+                       connect(this, SIGNAL(quit_debugger_thread()), emu->hDebugger, SLOT(doExit()));
+                       //connect(this, SIGNAL(quit_debugger_thread()), emu->hDebugger, SLOT(close()));
+                       connect(emu->hDebugger, SIGNAL(sig_finished()), this, SLOT(OnCloseDebugger()));
+                       connect(emu->hDebugger, SIGNAL(sig_put_string(QString)), emu->hDebugger, SLOT(put_string(QString)));
+                       emu->hDebugger->show();
+                       emu->hDebugger->run();
+               }
+       }
 }
 
 void Ui_MainWindow::OnCloseDebugger(void )
 {
-       if(emu->now_debugging) {
-               emu->close_debugger();
-               if(emu->hDebugger != NULL) delete emu->hDebugger;
-               emu->hDebugger = NULL;
-               emu->now_debugging = false;
-       }
+
+//     emu->close_debugger();
+       if(emu->now_debugging) {
+               if(emu->hDebugger->debugger_thread_param.running) {
+                       emit quit_debugger_thread();
+                       //emu->hDebugger->wait();
+               }
+               delete emu->hDebugger;
+               emu->hDebugger = NULL;
+               emu->now_debugging = false;
+       }
 }
 #endif
 
index 2ee4325..46c4bb2 100644 (file)
@@ -12,7 +12,7 @@ endif()
  
 add_library(qt_debugger
           qt_debugger.cpp
-#          debugger_thread.cpp
+          debugger_thread.cpp
          ${s_qt_debugger_headers_MOC}
 )
 
diff --git a/source/src/qt/debugger/debugger_thread.cpp b/source/src/qt/debugger/debugger_thread.cpp
new file mode 100644 (file)
index 0000000..f464721
--- /dev/null
@@ -0,0 +1,959 @@
+
+#include <QThread>
+#include <QMetaObject>
+#include <math.h>
+#include "./qt_debugger.h"
+#include "fileio.h"
+
+void CSP_DebuggerThread::my_printf(const _TCHAR *format, ...)
+{
+       _TCHAR buffer[4096];
+       va_list ap;
+
+       memset(buffer, 0x00, sizeof(buffer));
+       va_start(ap, format);
+       my_vstprintf_s(buffer, 4096, format, ap);
+       va_end(ap);
+       QString str(buffer);
+       if((logfile != NULL) && (logfile->IsOpened())) {
+                       logfile->Fwrite(buffer, strlen(buffer) * sizeof(_TCHAR), 1);
+       }
+       emit sig_put_string(str);
+}
+
+void CSP_DebuggerThread::my_putch(_TCHAR c)
+{
+       char buffer[2];
+       buffer[0] = (char)c;
+       buffer[1] = 0x00;
+       QString str(buffer);
+       if(logfile != NULL && logfile->IsOpened()) {
+               logfile->Fwrite(&c, sizeof(_TCHAR), 1);
+       }
+       emit sig_put_string(str);
+       //text->append(str);
+}
+
+uint32 CSP_DebuggerThread::my_hexatoi(_TCHAR *str)
+{
+       _TCHAR *s;
+       
+       if(str == NULL || strlen(str) == 0) {
+               return 0;
+       } else if(strlen(str) == 3 && str[0] == _T('\'') && str[2] == _T('\'')) {
+               // ank
+               return str[1] & 0xff;
+       } else if((s = strstr(str, _T(":"))) != NULL) {
+               // 0000:0000
+               s[0] = _T('\0');
+               return (my_hexatoi(str) << 4) + my_hexatoi(s + 1);
+       } else if(str[0] == _T('%')) {
+               // decimal
+               return atoi(str + 1);
+       }
+       return strtol(str, NULL, 16);
+}
+
+break_point_t *CSP_DebuggerThread::get_break_point(DEBUGGER *debugger, _TCHAR *command)
+{
+       if(command[0] == _T('B') || command[0] == _T('b')) {
+               return &debugger->bp;
+       } else if(command[0] == _T('R') || command[0] == _T('r')) {
+               return &debugger->rbp;
+       } else if(command[0] == _T('W') || command[0] == _T('w')) {
+               return &debugger->wbp;
+       } else if(command[0] == _T('I') || command[0] == _T('i')) {
+               return &debugger->ibp;
+       } else if(command[0] == _T('O') || command[0] == _T('o')) {
+               return &debugger->obp;
+       }
+       return NULL;
+}
+
+
+
+void CSP_DebuggerThread::call_debugger(QString str)
+{
+       //this->debugger_main(str);
+       this->do_string_input(str);
+}
+
+void CSP_DebuggerThread::display_break_point(void)
+{
+       getRegisterInfo();
+       trap_timer->stop();
+}
+
+void CSP_DebuggerThread::display_pc(void)
+{
+       _TCHAR buffer[1024];
+       dasm_addr = cpu->get_next_pc();
+                                       
+       cpu->debug_regs_info(buffer, 1024);
+       my_printf( _T("%s\n"), buffer);
+       cpu->debug_dasm(cpu->get_next_pc(), buffer, 1024);
+       my_printf( _T("next\t%08X  %s\n"), cpu->get_next_pc(), buffer);
+}
+
+void CSP_DebuggerThread::display_break_status(void)
+{
+       if(debugger->bp.hit) {
+               my_printf( _T("breaked at %08X\n"), cpu->get_next_pc());
+       } else if(debugger->rbp.hit) {
+               my_printf( _T("breaked at %08X: memory %08X was read at %08X\n"), cpu->get_next_pc(), debugger->rbp.hit_addr, cpu->get_pc());
+       } else if(debugger->wbp.hit) {
+               my_printf( _T("breaked at %08X: memory %08X was written at %08X\n"), cpu->get_next_pc(), debugger->wbp.hit_addr, cpu->get_pc());
+       } else if(debugger->ibp.hit) {
+               my_printf( _T("breaked at %08X: port %08X was read at %08X\n"), cpu->get_next_pc(), debugger->ibp.hit_addr, cpu->get_pc());
+       } else if(debugger->obp.hit) {
+               my_printf( _T("breaked at %08X: port %08X was written at %08X\n"), cpu->get_next_pc(), debugger->obp.hit_addr, cpu->get_pc());
+       }
+       debugger->bp.hit = debugger->rbp.hit = debugger->wbp.hit = debugger->ibp.hit = debugger->obp.hit = false;
+}
+
+void CSP_DebuggerThread::check_trap(void)
+{
+       volatile debugger_thread_t *p = d_params;
+       char buffer[1024];
+
+       memset(buffer, 0x00, sizeof(buffer));
+       if(trace_steps < 0) {
+               printf("!\n");
+               //if(!debugger->now_going) return;
+               if(!p->request_terminate && !debugger->now_suspended && !this->request_terminate) {
+                       if(debugger->hit()) {
+                               display_pc();
+                               display_break_status();
+                       }
+                       return;
+               }
+               debugger->now_going = false;
+               debugger->now_suspended = true;
+       }
+       // break cpu
+       display_pc();
+       if(debugger->hit()) {
+               display_break_status();
+       } else if(trace_steps < 0) {
+                my_printf( _T("breaked at %08X: Any key was pressed\n"), cpu->get_next_pc());
+       } else if(trace_steps == 0) {
+               my_printf("Trace OK\n");
+               debugger->now_going = false;
+               debugger->now_suspended = true;
+       }
+       if(trace_steps > 0) {
+               trace_steps--;
+               debugger->restore_break_points();
+               return;
+       }
+       //if(num >= 2) {
+       debugger->restore_break_points();
+       //}
+       emit sig_end_trap();
+}
+
+int CSP_DebuggerThread::debugger_main(QString command)
+{
+       
+       volatile debugger_thread_t *p = d_params;
+       QString scmd;
+       p->running = true;
+       
+       //DEVICE *cpu = p->vm->get_cpu(p->cpu_index);
+       //DEBUGGER *debugger = (DEBUGGER *)cpu->get_debugger();
+       if(debugger->now_going) {
+               if(!command.isEmpty()) {
+                       debugger->now_going = false;
+                       debugger->now_suspended = true;
+                       my_printf("Now Suspended\n");
+                       display_pc();
+                       display_break_status();
+                       return -1;
+               }
+       }
+       
+       //debugger->now_going = false;
+       debugger->now_debugging = true;
+       
+       uint32 prog_addr_mask = cpu->debug_prog_addr_mask();
+       uint32 data_addr_mask = cpu->debug_data_addr_mask();
+       
+       // initialize console
+       _TCHAR buffer[1024];
+       snprintf(buffer, 1024, _T("Debugger - %s"), _T(DEVICE_NAME));
+       bool cp932 = false; //(GetConsoleCP() == 932);
+
+       //while(!p->request_terminate) {
+       //my_printf( _T("- "));
+       if(command.isEmpty()) {
+               my_printf("");
+               scmd = prev_command;
+       } else {
+               my_printf("$%s\n", command.toUtf8().data());
+               scmd = command;
+       }
+
+       // get command
+       int ptr = 0;
+       // process command
+       if(!p->request_terminate && !this->request_terminate) {
+               QStringList s_params;
+               int num;
+               QString cmd;
+               s_params = scmd.split(" ");
+               num = s_params.count();
+               cmd = s_params.first().toUpper();
+               if(num < 1) {
+                       cmd = prev_command;
+                       num = 1;
+               } else {
+                       prev_command = cmd;
+               }
+               if(cmd == QString::fromUtf8("D")) {
+                       debugger->now_going = false;
+                       if(num <= 3) {
+                               uint32 start_addr = dump_addr;
+                               if(num >= 2) {
+                                       char *arg_1 = s_params.value(1).toUtf8().data();
+                                       start_addr = my_hexatoi(arg_1);
+                               }
+                               start_addr &= data_addr_mask;
+                               
+                               uint32 end_addr = start_addr + 8 * 16 - 1;
+                               if(num == 3) {
+                                       char *arg_2 = s_params.value(2).toUtf8().data();
+                                       end_addr = my_hexatoi(arg_2);
+                               }
+                               end_addr &= data_addr_mask;
+                               
+                               if(start_addr > end_addr) {
+                                       end_addr = data_addr_mask;
+                               }
+                               for(uint64 addr = start_addr & ~0x0f; addr <= end_addr; addr++) {
+                                       if(addr > data_addr_mask) {
+                                               end_addr = data_addr_mask;
+                                               break;
+                                       }
+                                       if((addr & 0x0f) == 0) {
+                                               my_printf( _T("%08X "), addr & data_addr_mask);
+                                               memset(buffer, 0, sizeof(buffer));
+                                       }
+                                       if(addr < start_addr) {
+                                               my_printf( _T("   "));
+                                               buffer[addr & 0x0f] = _T(' ');
+                                       } else {
+                                               uint32 data = cpu->debug_read_data8(addr & data_addr_mask);
+                                               my_printf( _T(" %02X"), data);
+                                               buffer[addr & 0x0f] = ((data >= 0x20 && data <= 0x7e) || (cp932 && data >= 0xa1 && data <= 0xdf)) ? data : _T('.');
+                                       }
+                                       if((addr & 0x0f) == 0x0f) {
+                                               my_printf( _T("  %s\n"), buffer);
+                                       }
+                               }
+                               if((end_addr & 0x0f) != 0x0f) {
+                                       for(uint32 addr = (end_addr & 0x0f) + 1; addr <= 0x0f; addr++) {
+                                               my_printf( _T("   "));
+                                       }
+                                       my_printf( _T("  %s\n"), buffer);
+                               }
+                               dump_addr = (end_addr + 1) & data_addr_mask;
+                               //prev_command.clear(); // remove parameters to dump continuously
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("E") || cmd == QString::fromUtf8("EB")) {
+                       debugger->now_going = false;
+                       if(num >= 3) {
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               uint32 addr = my_hexatoi(arg_1) & data_addr_mask;
+                               for(int i = 2; i < num; i++) {
+                                       char *arg_n = s_params.value(i).toUtf8().data();
+                                       cpu->debug_write_data8(addr, my_hexatoi(arg_n) & 0xff);
+                                       addr = (addr + 1) & data_addr_mask;
+                               }
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("EW")) {
+                       debugger->now_going = false;
+                       if(num >= 3) {
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               uint32 addr = my_hexatoi(arg_1) & data_addr_mask;
+                               for(int i = 2; i < num; i++) {
+                                       char *arg_n = s_params.value(i).toUtf8().data();
+                                       cpu->debug_write_data16(addr, my_hexatoi(arg_n) & 0xffff);
+                                       addr = (addr + 2) & data_addr_mask;
+                               }
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("ED")) {
+                       debugger->now_going = false;
+                       if(num >= 3) {
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               uint32 addr = my_hexatoi(arg_1) & data_addr_mask;
+                               for(int i = 2; i < num; i++) {
+                                       char *arg_n = s_params.value(i).toUtf8().data();
+                                       cpu->debug_write_data32(addr, my_hexatoi(arg_n));
+                                       addr = (addr + 4) & data_addr_mask;
+                               }
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("EA")) {
+                       debugger->now_going = false;
+                       if(num >= 3) {
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               uint32 addr = my_hexatoi(arg_1) & data_addr_mask;
+                               QString sbuffer;
+                               QStringList slist;
+                               sbuffer = prev_command;
+                               slist = sbuffer.split("\"");
+                               if(!slist.isEmpty()) {
+                                       char *token = slist.first().toUtf8().data();
+                                       if(token == NULL) {
+                                               p->running = false;
+                                               emit sig_text_clear();
+                                               return 0;
+                                       }
+                                       int len = strlen(token);
+                                       for(int i = 0; i < len; i++) {
+                                               cpu->debug_write_data8(addr, token[i] & 0xff);
+                                               addr = (addr + 1) & data_addr_mask;
+                                       }
+                               } else {
+                                       my_printf( _T("invalid parameter\n"));
+                               }
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("I") || cmd == QString::fromUtf8("IB")) {
+                       debugger->now_going = false;
+                       if(num == 2) {
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               my_printf( _T("%02X\n"), cpu->debug_read_io8(my_hexatoi(arg_1) & 0xff));
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("IW")) {
+                       debugger->now_going = false;
+                       if(num >= 2) {
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               my_printf( _T("%02X\n"), cpu->debug_read_io16(my_hexatoi(arg_1)) & 0xffff);
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("ID")) {
+                       debugger->now_going = false;
+                       if(num >= 2) {
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               my_printf( _T("%02X\n"), cpu->debug_read_io32(my_hexatoi(arg_1)));
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("O") || cmd == QString::fromUtf8("OB")) {
+                       debugger->now_going = false;
+                       if(num == 3) {
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               char *arg_2 = s_params.value(2).toUtf8().data();
+                               cpu->debug_write_io8(my_hexatoi(arg_1), my_hexatoi(arg_2) & 0xff);
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("OW")) {
+                       debugger->now_going = false;
+                       if(num == 3) {
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               char *arg_2 = s_params.value(2).toUtf8().data();
+                               cpu->debug_write_io16(my_hexatoi(arg_1), my_hexatoi(arg_2) & 0xffff);
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("OD")) {
+                       debugger->now_going = false;
+                       if(num == 3) {
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               char *arg_2 = s_params.value(2).toUtf8().data();
+                               cpu->debug_write_io32(my_hexatoi(arg_1), my_hexatoi(arg_2) & 0xffff);
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("R")) {
+                       debugger->now_going = false;
+                       my_printf( _T("CPU DOMAIN=%d\n"), cpu_index);
+                       if(num == 1) {
+                               cpu->debug_regs_info(buffer, 1024);
+                               my_printf( _T("%s\n"), buffer);
+                       } else if(num == 3) {
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               char *arg_2 = s_params.value(2).toUtf8().data();
+                               if(!cpu->debug_write_reg(arg_1, my_hexatoi(arg_2))) {
+                                       my_printf( _T("unknown register %s\n"), arg_1);
+                               }
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("S")) {
+                       debugger->now_going = false;
+                       if(num >= 4) {
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               char *arg_2 = s_params.value(2).toUtf8().data();
+                               uint32 start_addr = my_hexatoi(arg_1) & data_addr_mask;
+                               uint32 end_addr = my_hexatoi(arg_2) & data_addr_mask;
+                               uint8 list[32];
+                               char *arg_n = NULL;
+                               for(int i = 3, j = 0; i < num; i++, j++) {
+                                       arg_n = s_params.value(i).toUtf8().data();
+                                       if(arg_n == NULL) break;
+                                       list[j] = my_hexatoi(arg_n);
+                               }
+                               for(uint64 addr = start_addr; addr <= end_addr; addr++) {
+                                       bool found = true;
+                                       for(int i = 3, j = 0; i < num; i++, j++) {
+                                               if(cpu->debug_read_data8((addr + j) & data_addr_mask) != list[j]) {
+                                                       found = false;
+                                                       break;
+                                               }
+                                       }
+                                       if(found) {
+                                               my_printf( _T("%08X\n"), addr);
+                                       }
+                               }
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("UW")) {
+                       debugger->now_going = false;
+                       if((num <= 4) && (num >= 2)) {
+                               uint32 start_a, end_a;
+                               int filename_num = 1;
+                               start_a = dasm_addr;
+                               if(num >= 3) {
+                                       char *arg_1 = s_params.value(1).toUtf8().data();
+                                       start_a = my_hexatoi(arg_1) & prog_addr_mask;
+                                       filename_num = 2;
+                               }
+                               
+                               if(num == 4) {
+                                               char *arg_2 = s_params.value(2).toUtf8().data();
+                                               end_a = my_hexatoi(arg_2) & prog_addr_mask;
+                                               filename_num = 3;
+                                       } else {
+                                               end_a = start_a + 0x100;
+                                       }
+                                       char *arg_name = s_params.value(filename_num).toUtf8().data();
+
+                                       if(arg_name[0] == _T('\"')) {
+                                               QString sbuffer;
+                                               QStringList slist;
+
+                                               sbuffer = prev_command;
+                                               slist = sbuffer.split("\"");
+                                               if(!slist.isEmpty()) {
+                                                       strncpy(debugger->file_path, slist.first().toUtf8().data(), _MAX_PATH);
+                                               } else {
+                                                       my_printf( _T("invalid parameter\n"));
+                                                       filename_num = -1;
+                                               }
+                                       }
+                                       if(end_a < start_a) {
+                                               uint32 tmp_a;
+                                               tmp_a = start_a;
+                                               start_a = end_a;
+                                               end_a = tmp_a;
+                                       }
+                                       if(filename_num >= 1) {
+                                               FILEIO* fio = new FILEIO();
+                                               _TCHAR dasm_str_buffer[1024];
+                                               _TCHAR stream_buffer[1024];
+                                               int addrcount = (int)(end_a - start_a);
+                                               if(fio->Fopen(debugger->file_path, FILEIO_WRITE_ASCII)) {
+                                                       for(dasm_addr = start_a; addrcount > 0;) {
+                                                               memset(dasm_str_buffer, 0x00, sizeof(dasm_str_buffer));
+                                                               memset(stream_buffer, 0x00, sizeof(stream_buffer));
+                                                               int len = cpu->debug_dasm(dasm_addr, dasm_str_buffer, 1024);
+                                                               if(len > 0) {
+                                                                       snprintf(stream_buffer, 1024, _T("%08X  %s\n"), dasm_addr, dasm_str_buffer);
+                                                                       fio->Fwrite(stream_buffer, strlen(stream_buffer), 1); 
+                                                                       dasm_addr = (dasm_addr + len) & prog_addr_mask;
+                                                                       addrcount -= len;
+                                                               } else {
+                                                                       break;
+                                                               }
+                                                       }
+                                                       fio->Fclose();
+                                                       delete fio;
+                                               }
+                                       }
+                                  
+                                       //prev_command.clear(); // remove parameters to disassemble continuously
+                       } else {
+                               my_printf( _T("invalid parameter number\n"));
+                       }
+               } else if(cmd == QString::fromUtf8("U")) {
+                       debugger->now_going = false;
+                               if(num <= 3) {
+                                       if(num >= 2) {
+                                               char *arg_1 = s_params.value(1).toUtf8().data();
+                                               dasm_addr = my_hexatoi(arg_1) & prog_addr_mask;
+                                       }
+                                       if(num == 3) {
+                                               char *arg_2 = s_params.value(2).toUtf8().data();
+                                               uint32 end_addr = my_hexatoi(arg_2) & prog_addr_mask;
+                                               while(dasm_addr <= end_addr) {
+                                                       int len = cpu->debug_dasm(dasm_addr, buffer, 1024);
+                                                       my_printf( _T("%08X  %s\n"), dasm_addr, buffer);
+                                                       dasm_addr = (dasm_addr + len) & prog_addr_mask;
+                                               }
+                                       } else {
+                                               for(int i = 0; i < 16; i++) {
+                                                       int len = cpu->debug_dasm(dasm_addr, buffer, 1024);
+                                                       my_printf( _T("%08X  %s\n"), dasm_addr, buffer);
+                                                       dasm_addr = (dasm_addr + len) & prog_addr_mask;
+                                               }
+                                       }
+                                       //prev_command.clear(); // remove parameters to disassemble continuously
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+               } else if(cmd == QString::fromUtf8("H")) {
+                       debugger->now_going = false;
+                               if(num == 3) {
+                                       char *arg_1 = s_params.value(1).toUtf8().data();
+                                       char *arg_2 = s_params.value(2).toUtf8().data();
+                                       uint32 l = my_hexatoi(arg_1);
+                                       uint32 r = my_hexatoi(arg_2);
+                                       my_printf( _T("%08X  %08X\n"), l + r, l - r);
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+               } else if(cmd == QString::fromUtf8("N")) {
+                       debugger->now_going = false;
+                       char *arg_1 = s_params.value(1).toUtf8().data();
+                       if(num >= 2 && arg_1[0] == _T('\"')) {
+                                       QString sbuffer;
+                                       QStringList slist;
+                                       sbuffer = prev_command;
+                                       slist = sbuffer.split("\"");
+                                       if(!slist.isEmpty()) {
+                                               strncpy(debugger->file_path, slist.first().toUtf8().data(), _MAX_PATH);
+                                       } else {
+                                               my_printf( _T("invalid parameter\n"));
+                                       }
+                               } else if(num == 2) {
+                                       strncpy(debugger->file_path, arg_1, _MAX_PATH);
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+               } else if(cmd == QString::fromUtf8("L")) {
+                       debugger->now_going = false;
+                       if(num == 3) {
+                                       char *arg_1 = s_params.value(1).toUtf8().data();
+                                       char *arg_2 = s_params.value(2).toUtf8().data();
+                                       uint32 start_addr = my_hexatoi(arg_1) & data_addr_mask, end_addr = my_hexatoi(arg_2) & data_addr_mask;
+                                       FILEIO* fio = new FILEIO();
+                                       if(fio->Fopen(debugger->file_path, FILEIO_READ_BINARY)) {
+                                               for(uint32 addr = start_addr; addr <= end_addr; addr++) {
+                                                       int data = fio->Fgetc();
+                                                       if(data == EOF) {
+                                                               break;
+                                                       }
+                                                       cpu->debug_write_data8(addr & data_addr_mask, data);
+                                               }
+                                               fio->Fclose();
+                                       } else {
+                                               my_printf( _T("can't open %s\n"), debugger->file_path);
+                                       }
+                                       delete fio;
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+               } else if(cmd == QString::fromUtf8("W")) {
+                       debugger->now_going = false;
+                               if(num == 3) {
+                                       char *arg_1 = s_params.value(1).toUtf8().data();
+                                       char *arg_2 = s_params.value(2).toUtf8().data();
+                                       uint32 start_addr = my_hexatoi(arg_1) & data_addr_mask, end_addr = my_hexatoi(arg_2) & data_addr_mask;
+                                       FILEIO* fio = new FILEIO();
+                                       if(fio->Fopen(debugger->file_path, FILEIO_WRITE_BINARY)) {
+                                               for(uint32 addr = start_addr; addr <= end_addr; addr++) {
+                                                       fio->Fputc(cpu->debug_read_data8(addr & data_addr_mask));
+                                               }
+                                               fio->Fclose();
+                                       } else {
+                                               my_printf( _T("can't open %s\n"), debugger->file_path);
+                                       }
+                                       delete fio;
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+               } else if(cmd == QString::fromUtf8( "BP") || cmd == QString::fromUtf8("RBP") || cmd == QString::fromUtf8("WBP")) {
+                       debugger->now_going = false;
+                               break_point_t *bp = get_break_point(debugger, cmd.toUtf8().data());
+                               if(num == 2) {
+                                       char *arg_1 = s_params.value(1).toUtf8().data();
+                                       uint32 addr = my_hexatoi(arg_1);
+                                       bool found = false;
+                                       for(int i = 0; i < MAX_BREAK_POINTS && !found; i++) {
+                                               if(bp->table[i].status == 0 || (bp->table[i].addr == addr && bp->table[i].mask == prog_addr_mask)) {
+                                                       bp->table[i].addr = addr;
+                                                       bp->table[i].mask = prog_addr_mask;
+                                                       bp->table[i].status = 1;
+                                                       found = true;
+                                               }
+                                       }
+                                       if(!found) {
+                                               my_printf( _T("too many break points\n"));
+                                       }
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+               } else if(cmd == QString::fromUtf8("IBP") || cmd == QString::fromUtf8("OBP")) {
+                       debugger->now_going = false;
+                               break_point_t *bp = get_break_point(debugger, cmd.toUtf8().data());
+                               if(num == 2 || num == 3) {
+                                       char *arg_1 = s_params.value(1).toUtf8().data();
+                                       uint32 addr = my_hexatoi(arg_1), mask = 0xff;
+                                       if(num == 3) {
+                                               char *arg_2 = s_params.value(2).toUtf8().data();
+                                               mask = my_hexatoi(arg_2);
+                                       }
+                                       bool found = false;
+                                       for(int i = 0; i < MAX_BREAK_POINTS && !found; i++) {
+                                               if(bp->table[i].status == 0 || (bp->table[i].addr == addr && bp->table[i].mask == mask)) {
+                                                       bp->table[i].addr = addr;
+                                                       bp->table[i].mask = mask;
+                                                       bp->table[i].status = 1;
+                                                       found = true;
+                                               }
+                                       }
+                                       if(!found) {
+                                               my_printf( _T("too many break points\n"));
+                                       }
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+               } else if(cmd == QString::fromUtf8("BC") || cmd == QString::fromUtf8("RBC") || cmd == QString::fromUtf8("WBC") || cmd == QString::fromUtf8("IBC") || cmd == QString::fromUtf8("OBC")) {
+                       debugger->now_going = false;
+                               char *arg_1 = s_params.value(1).toUtf8().data();
+                               break_point_t *bp = get_break_point(debugger, cmd.toUtf8().data());
+                               if(num == 2 && strcasecmp(arg_1, _T("ALL"))) {
+                                       memset(bp->table, 0, sizeof(bp->table));
+                               } else if(num >= 2) {
+                                       char *arg_n;
+                                       for(int i = 1; i < num; i++) {
+                                               arg_n = s_params.value(i).toUtf8().data();
+                                               if(arg_n == NULL) break;
+                                               int index = my_hexatoi(arg_n);
+                                               if(!(index >= 1 && index <= MAX_BREAK_POINTS)) {
+                                                       my_printf( _T("invalid index %x\n"), index);
+                                               } else {
+                                                       bp->table[index - 1].addr = bp->table[index - 1].mask = 0;
+                                                       bp->table[index - 1].status = 0;
+                                               }
+                                       }
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+               } else if(cmd == QString::fromUtf8("BD") || cmd == QString::fromUtf8("RBD") || cmd == QString::fromUtf8("WBD") || cmd == QString::fromUtf8("IBD") || cmd == QString::fromUtf8("OBD") ||
+                                 cmd == QString::fromUtf8("BE") || cmd == QString::fromUtf8("RBE") || cmd == QString::fromUtf8("WBE") || cmd == QString::fromUtf8("IBE") || cmd == QString::fromUtf8("OBE")) {
+                       debugger->now_going = false;
+                                               break_point_t *bp = get_break_point(debugger, cmd.toUtf8().data());
+                                               QString m1 = cmd.mid(1, 1);
+                                               QString m2 = cmd.mid(2, 1);
+                                               
+                                               bool enabled = (m1 == QString::fromUtf8("E") || m1 == QString::fromUtf8("e") ||
+                                                                               m2 == QString::fromUtf8("E") || m2 == QString::fromUtf8("e"));
+                                               char *arg_1 = s_params.value(1).toUtf8().data();
+                                               if(num == 2 && strcasecmp(arg_1, _T("ALL"))) {
+                                       for(int i = 0; i < MAX_BREAK_POINTS; i++) {
+                                               if(bp->table[i].status != 0) {
+                                                       bp->table[i].status = enabled ? 1 : -1;
+                                               }
+                                       }
+                                               } else if(num >= 2) {
+                                                       for(int i = 1; i < num; i++) {
+                                                               char *arg_n = s_params.value(i).toUtf8().data();
+                                                               if(arg_n == NULL) break;
+                                                               int index = my_hexatoi(arg_n);
+                                                               if(!(index >= 1 && index <= MAX_BREAK_POINTS)) {
+                                                                       my_printf( _T("invalid index %x\n"), index);
+                                                               } else if(bp->table[index - 1].status == 0) {
+                                                                       my_printf( _T("break point %x is null\n"), index);
+                                                               } else {
+                                                                       bp->table[index - 1].status = enabled ? 1 : -1;
+                                                               }
+                                                       }
+                                               } else {
+                                                       my_printf( _T("invalid parameter number\n"));
+                                               }
+               } else if(cmd == QString::fromUtf8("BL") || cmd == QString::fromUtf8("RBL") || cmd == QString::fromUtf8("WBL")) {
+                       debugger->now_going = false;
+                       if(num == 1) {
+                                       break_point_t *bp = get_break_point(debugger, cmd.toUtf8().data());
+                                       for(int i = 0; i < MAX_BREAK_POINTS; i++) {
+                                               if(bp->table[i].status) {
+                                                       my_printf( _T("%d %c %08X\n"), i + 1, bp->table[i].status == 1 ? _T('e') : _T('d'), bp->table[i].addr);
+                                               }
+                                       }
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+                       } else if(cmd == QString::fromUtf8("IBL") || cmd == QString::fromUtf8("OBL")) {
+                               if(num == 1) {
+                                       break_point_t *bp = get_break_point(debugger, cmd.toUtf8().data());
+                                       for(int i = 0; i < MAX_BREAK_POINTS; i++) {
+                                               if(bp->table[i].status) {
+                                                       my_printf( _T("%d %c %08X %08X\n"), i + 1, bp->table[i].status == 1 ? _T('e') : _T('d'), bp->table[i].addr, bp->table[i].mask);
+                                               }
+                                       }
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+                       } else if(cmd == QString::fromUtf8("G")) {
+                               if(num == 1 || num == 2) {
+                                       if(num >= 2) {
+                                               char *arg_1 = s_params.value(1).toUtf8().data();
+                                               debugger->store_break_points();
+                                               debugger->bp.table[0].addr = my_hexatoi(arg_1) & prog_addr_mask;
+                                               debugger->bp.table[0].mask = prog_addr_mask;
+                                               debugger->bp.table[0].status = 1;
+                                       }
+                                       debugger->now_going = true;
+                                       debugger->now_suspended = false;
+                                       trace_steps = -1;
+                                       pausing = true;
+                                       emit sig_start_trap();
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+               } else if(cmd == QString::fromUtf8("T")) {
+                       if(num == 1 || num == 2) {
+                               int steps = 1;
+                               if(num >= 2) {
+                                       char *arg_1 = s_params.value(1).toUtf8().data();
+                                       steps = my_hexatoi(arg_1);
+                               }
+                               if(steps >= 1) trace_steps = steps;
+                                       debugger->now_going = false;
+                                       debugger->now_suspended = false;
+                                       emit sig_start_trap();
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+               } else if(cmd == QString::fromUtf8("Q")) {
+                       debugger->now_going = false;
+                       p->running = false;
+                       p->request_terminate = true;
+                       this->request_terminate = true;
+                       emit quit_debugger_thread();
+                       return -1;
+               } else if(cmd == QString::fromUtf8(">")) {
+                       if(num >= 2) {
+                               if(logfile != NULL) {
+                                       if(logfile->IsOpened()) {
+                                               logfile->Fclose();
+                                       }
+                                       delete logfile;
+                                       logfile = NULL;
+                               }
+                               logfile = new FILEIO();
+                               logfile->Fopen(s_params.value(1).toUtf8().data(), FILEIO_WRITE_ASCII);
+                               my_printf(_T("Log Opened %s .\n"), s_params.value(1).toUtf8().data());
+                       } else {
+                               if(logfile != NULL) {
+                                       if(logfile->IsOpened()) {
+                                               logfile->Fclose();
+                                       }
+                                       delete logfile;
+                                       logfile = NULL;
+                                       my_printf(_T("LOG closed.\n"));
+                               } else {
+                                       my_printf(_T("invalid parameter number\n"));
+                               }
+                       }
+               } else if(cmd == QString::fromUtf8("!")) {
+                       char *arg_1 = s_params.value(1).toUtf8().data();
+                       char *arg_2 = s_params.value(2).toUtf8().data();
+                       debugger->now_going = false;
+                       if(num == 1) {
+                               my_printf( _T("invalid parameter number\n"));
+                       } else if(strcasecmp(arg_1, _T("RESET"))) {
+                               if(num == 2) {
+                                       p->vm->reset();
+                               } else if(num == 3) {
+                                       if(strcasecmp(arg_2, _T("ALL"))) {
+                                               p->vm->reset();
+                                       } if(strcasecmp(arg_2, _T("CPU"))) {
+                                               cpu->reset();
+                                       } else {
+                                               my_printf( _T("unknown device %s\n"), arg_2);
+                                       }
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+                       } else if(strcasecmp(arg_1, _T("KEY"))) {
+                               if(num == 3 || num == 4) {
+                                       int code =  my_hexatoi(arg_1) & 0xff, msec = 100;
+                                       if(num == 4) {
+                                               char *arg_3 = s_params.value(3).toUtf8().data();
+                                               msec = my_hexatoi(arg_3);
+                                       }
+#ifdef SUPPORT_VARIABLE_TIMING
+                                       //p->emu->key_buffer()[code] = (int)fmax(p->vm->frame_rate() * (double)msec / 1000.0 + 0.5, 1.0);
+#else
+                                       //p->emu->key_buffer()[code] = (int)fmax(FRAMES_PER_SEC * (double)msec / 1000.0 + 0.5, 1.0);
+#endif
+#ifdef NOTIFY_KEY_DOWN
+                                       p->vm->key_down(code, false);
+#endif
+                               } else {
+                                       my_printf( _T("invalid parameter number\n"));
+                               }
+                       } else {
+                               my_printf( _T("unknown command ! %s\n"), arg_1);
+                       }
+               } else if(cmd == QString::fromUtf8("?")) {
+                       debugger->now_going = false;
+                       my_printf( _T("D [<range>] - dump memory\n"));
+                       my_printf( _T("E[{B,W,D}] <address> <list> - edit memory (byte,word,dword)\n"));
+                       my_printf( _T("EA <address> \"<value>\" - edit memory (ascii)\n"));
+                       my_printf( _T("I[{B,W,D}] <port> - input port (byte,word,dword)\n"));
+                       my_printf( _T("O[{B,W,D}] <port> <value> - output port (byte,word,dword)\n"));
+                       my_printf( _T("R - show register(s)\n"));
+                       my_printf( _T("R <reg> <value> - edit register\n"));
+                       my_printf( _T("S <range> <list> - search\n"));
+                       my_printf( _T("U [<range>] - unassemble\n"));
+                       my_printf( _T("UW [<start>] [<end>] filename - unassemble to file\n"));
+                               
+                       my_printf( _T("H <value> <value> - hexadd\n"));
+                       my_printf( _T("N <filename> - name\n"));
+                       my_printf( _T("L <range> - load file\n"));
+                       my_printf( _T("W <range> - write file\n"));
+                               
+                       my_printf( _T("BP <address> - set breakpoint\n"));
+                       my_printf( _T("{R,W}BP <address> - set breakpoint (break at memory access)\n"));
+                       my_printf( _T("{I,O}BP <port> [<mask>] - set breakpoint (break at i/o access)\n"));
+                       my_printf( _T("[{R,W,I,O}]B{C,D,E} {all,<list>} - clear/disable/enable breakpoint(s)\n"));
+                       my_printf( _T("[{R,W,I,O}]BL - list breakpoint(s)\n"));
+                               
+                       my_printf( _T("G - go (press return key to break)\n"));
+                       my_printf( _T("G <address> - go and break at address\n"));
+                       my_printf( _T("T [<count>] - trace\n"));
+                       my_printf( _T("Q - quit\n"));
+                               
+                       my_printf( _T("! reset [cpu] - reset\n"));
+                       my_printf( _T("! key <code> [<msec>] - press key\n"));
+                       
+                       my_printf( _T("<value> - hexa, decimal(%%d), ascii('a')\n"));
+               } else {
+                       my_printf( _T("unknown command %s\n"), cmd.toUtf8().data());
+               }
+       }
+       p->running = false;
+       emit sig_text_clear();
+                               
+       return 0;
+}
+
+void CSP_DebuggerThread::getRegisterInfo()
+{
+       _TCHAR buffer[2048];
+       uint32 p_pc = cpu->get_pc();
+
+       memset(buffer, 0x00, sizeof(buffer));
+       
+       cpu->debug_regs_info(buffer, 2048);
+       my_printf(_T("CPU Domain #%d\n%s\n"), cpu_index, buffer);
+       
+       
+       my_printf(_T("breaked at %08X\n"), p_pc);
+       
+       memset(buffer, 0x00, sizeof(buffer));
+       cpu->debug_dasm(p_pc, buffer, 2048);
+       my_printf(_T("%s\nnext\t%08X\n"), buffer, cpu->get_next_pc());
+}
+
+void CSP_DebuggerThread::quit_debugger()
+{
+       debugger->now_going = false;
+       d_params->running = false;
+       d_params->request_terminate = true;
+       this->request_terminate = true;
+       //this->wait(1000);
+       emit quit_debugger_thread();
+       //debugger_main(QString::fromUtf8("Q"));
+}
+
+void CSP_DebuggerThread::do_string_input(QString s)
+{
+       if(pausing) {
+               pausing = false;
+               getRegisterInfo();
+               return;
+       }
+       debugger_main(s);
+}
+
+void CSP_DebuggerThread::run()
+{
+       QString str = QString::fromUtf8(_T("Debugger CPU #")) + QString::number(cpu_index);
+       emit sig_set_title(str);
+
+       pausing = false;
+       d_params->running = true;
+       d_params->request_terminate = false;
+       this->request_terminate = false;
+       dasm_addr = cpu->get_next_pc();
+       this->getRegisterInfo();
+       debugger->now_going = false;
+       debugger->now_debugging = true;
+
+       while(!this->request_terminate) {
+               this->msleep(10);
+       }
+       //emit quit_debugger_thread();
+       this->quit();
+}
+
+CSP_DebuggerThread::CSP_DebuggerThread(QObject *parent, debugger_thread_t *th) : QThread(parent)
+{
+       logfile = NULL;
+       d_params = th;
+       cpu = d_params->vm->get_cpu(d_params->cpu_index);
+       cpu_index = d_params->cpu_index;
+       debugger = (DEBUGGER *)cpu->get_debugger();
+       
+       trap_timer = new QTimer(this);
+       trap_timer->setInterval(3);
+       trap_timer->setSingleShot(false);
+       prev_command.clear();
+       dump_addr = 0;
+       dasm_addr = 0;
+       pausing = false;
+       
+       trace_steps = 0;
+       connect(this, SIGNAL(sig_start_trap()), trap_timer, SLOT(start()));
+       connect(this, SIGNAL(sig_end_trap()),   this, SLOT(display_break_point()));
+       connect(trap_timer, SIGNAL(timeout()),  this, SLOT(check_trap()));
+       connect(this, SIGNAL(started()), this, SLOT(run()));
+}
+
+CSP_DebuggerThread::~CSP_DebuggerThread()
+{
+       if(logfile != NULL) {
+               if(logfile->IsOpened()) {
+                       logfile->Fclose();
+               }
+               delete logfile;
+               logfile = NULL;
+       }
+       trap_timer->stop();
+       delete trap_timer;
+}
+
+void EMU::initialize_debugger()
+{
+       now_debugging = false;
+}
+
index 184afbd..b78b337 100644 (file)
@@ -22,7 +22,8 @@
 #include "../../vm/vm.h"
 #include "../../fileio.h"
 #include "qt_debugger.h"
-#include "osd.h"
+//#include <QThread>
+//#include <QMainWindow>
 
 
 #ifdef USE_DEBUGGER
@@ -39,9 +40,24 @@ void CSP_Debugger::cmd_clear()
        text->moveCursor(QTextCursor::End);
 }
 
+
+void CSP_Debugger::doExit2(void)
+{
+       emit sig_close_debugger();
+}
+
 void CSP_Debugger::doExit(void)
 {
-       //p_emu->close_debugger();
+       DEVICE *cpu = debugger_thread_param.vm->get_cpu(debugger_thread_param.cpu_index);
+       DEBUGGER *debugger = (DEBUGGER *)cpu->get_debugger();
+       debugger_thread_param.request_terminate = true;
+       
+       try {
+               debugger->now_debugging = debugger->now_going = debugger->now_suspended = false;
+       } catch(...) {
+       }
+       // release console
+       debugger_thread_param.running = false;
        emit sig_finished();
 }
 
@@ -52,32 +68,47 @@ void CSP_Debugger::stop_polling()
 
 void CSP_Debugger::call_debugger(void)
 {
-       emit sig_call_debugger(text_command->text());
+       //emit sig_call_debugger(text_command->text());
+       main_thread->call_debugger(text_command->text());
 }
 
 void CSP_Debugger::run(void)
 {
+       main_thread = new CSP_DebuggerThread(NULL, &debugger_thread_param);
+       main_thread->setObjectName(QString::fromUtf8("Debugger"));
+       main_thread->moveToThread(main_thread);
+       //main_thread = new CSP_DebuggerThread(this, &debugger_thread_param);
+       
        connect(text_command, SIGNAL(editingFinished()), this, SLOT(call_debugger()));
-       connect(this, SIGNAL(sig_call_debugger(QString)), p_osd, SLOT(do_write_inputdata(QString)), Qt::DirectConnection);
+       connect(this, SIGNAL(sig_call_debugger(QString)), main_thread, SLOT(call_debugger(QString)));
+       
+       connect(main_thread, SIGNAL(sig_text_clear()), this, SLOT(cmd_clear()));
+       connect(main_thread, SIGNAL(sig_put_string(QString)), this, SLOT(put_string(QString)));
+       
+       connect(main_thread, SIGNAL(finished()), this, SLOT(doExit()));
+       connect(main_thread, SIGNAL(quit_debugger_thread()), this, SLOT(doExit()));
        
-       connect(p_osd, SIGNAL(sig_debugger_finished()), this, SLOT(doExit()));
-       connect(this, SIGNAL(sig_finished()), p_osd, SLOT(do_close_debugger_thread()));
-       connect(this, SIGNAL(destroyed()), this, SLOT(doExit()));
-       connect(parent_object, SIGNAL(quit_debugger_thread()), this, SLOT(close()));
        connect(this, SIGNAL(sig_finished()), this, SLOT(close()));
+       connect(this, SIGNAL(destroyed()), this, SLOT(doExit()));
+       connect(this, SIGNAL(sig_close_debugger()), main_thread, SLOT(quit_debugger()));
        
+       //connect(parent_object, SIGNAL(quit_debugger_thread()), this, SLOT(doExit2()));
+       connect(parent_object, SIGNAL(quit_debugger_thread()), this, SLOT(close()));
+                                                                 
+       connect(this, SIGNAL(sig_start_debugger()), main_thread, SLOT(start()));
+       main_thread->start();
        //emit sig_start_debugger();
 }
 
 void CSP_Debugger::closeEvent(QCloseEvent *event)
 {
+       main_thread->terminate();
        doExit();
 }
 
-CSP_Debugger::CSP_Debugger(QWidget *parent, OSD *osd) : QWidget(parent, Qt::Window)
+CSP_Debugger::CSP_Debugger(QWidget *parent) : QWidget(parent, Qt::Window)
 {
        widget = this;
-       p_osd = osd;
        
        parent_object = parent;
        text = new QTextEdit(this);
@@ -91,6 +122,7 @@ CSP_Debugger::CSP_Debugger(QWidget *parent, OSD *osd) : QWidget(parent, Qt::Wind
        text_command->setReadOnly(false);
        text_command->setEnabled(true);
        text_command->clear();
+       //connect(text_command, SIGNAL(editingFinished()), this, SLOT(call_debugger()));
        
        VBoxWindow = new QVBoxLayout;
 
index cb168bf..fbd7af0 100644 (file)
 #include "../../vm/debugger.h"
 #include "../../vm/vm.h"
 #include "../../fileio.h"
-#include "osd.h"
 
 #define MAX_COMMAND_LEN        64
+       
+class CSP_DebuggerThread : public QThread
+{
+       Q_OBJECT
+
+protected:
+       debugger_thread_t *d_params;
+       DEBUGGER *debugger;
+       DEVICE *cpu;
+       uint32 cpu_index;
+       bool pausing;
+       
+       FILEIO *logfile;
+       QTimer *trap_timer;
+       QString prev_command;
+       uint32 dump_addr;
+       uint32 dasm_addr;
+       int trace_steps;
+       bool request_terminate;
+       
+       break_point_t *get_break_point(DEBUGGER *debugger, _TCHAR *command);
+       uint32 my_hexatoi(_TCHAR *str);
+       void my_putch(_TCHAR c);
+       void my_printf(const _TCHAR *format, ...);
+       void getRegisterInfo();
+       void display_break_status(void);
+       void display_pc(void);
+       
+public:
+       CSP_DebuggerThread(QObject *parent, debugger_thread_t *th);
+       ~CSP_DebuggerThread();
+public slots:
+       void run();
+       virtual int debugger_main(QString command);
+       void call_debugger(QString);
+       void check_trap();
+       void display_break_point();
+       void quit_debugger();
+       void do_string_input(QString s);
+signals:
+       int sig_start_trap();
+       int sig_end_trap();
+       int sig_text_clear();
+       int sig_put_string(QString);
+       int quit_debugger_thread();
+       void sig_set_title(QString);
+};
 
 class CSP_Debugger : public QWidget
 {
@@ -40,17 +86,20 @@ class CSP_Debugger : public QWidget
        QTextEdit *text;
        QLineEdit *text_command;
        QVBoxLayout *VBoxWindow;
-       OSD *p_osd;
+       CSP_DebuggerThread *main_thread;
        
  protected:
        //QFont font;// = QApplication::font();
        //QMainWindow  *debug_window;
  public:
-       CSP_Debugger(QWidget *parent, OSD *osd);
+       CSP_Debugger(QWidget *parent);
        ~CSP_Debugger();
+       debugger_thread_t debugger_thread_param;
        void closeEvent(QCloseEvent *event);
+       
 public slots:
        void doExit(void);
+       void doExit2(void);
        void stop_polling();
        void put_string(QString);
        void cmd_clear();
index 712238a..696b94e 100644 (file)
@@ -52,6 +52,9 @@ void OSD::set_draw_thread(DrawThreadClass *handler)
        connect(this, SIGNAL(sig_save_screen(const char *)), glv, SLOT(do_save_frame_screen(const char *)));
        connect(this, SIGNAL(sig_close_window()), parent_thread, SLOT(doExit()));
        connect(this, SIGNAL(sig_resize_vm_screen(QImage *, int, int)), glv, SLOT(do_set_texture_size(QImage *, int, int)));
+       connect(this, SIGNAL(sig_console_input_string(QString)), parent_thread, SLOT(do_call_debugger_command(QString)));
+       connect(parent_thread, SIGNAL(sig_debugger_input(QString)), this, SLOT(do_set_input_string(QString)));
+       connect(parent_thread, SIGNAL(sig_quit_debugger()), this, SLOT(do_close_debugger_thread()));
 }
 
 void OSD::initialize(int rate, int samples)
@@ -69,7 +72,7 @@ void OSD::initialize(int rate, int samples)
        memset(app_path, 0x00, sizeof(app_path));
        strncpy(app_path, tmp_path.toUtf8().constData(), _MAX_PATH);
        
-       osd_console_input = NULL;
+       memset(console_string, 0x00, sizeof(console_string));
        osd_console_opened = false;
        //CoInitialize(NULL);
        initialize_input();
@@ -165,3 +168,30 @@ void OSD::create_date_file_name(_TCHAR *name, int length, const _TCHAR *extensio
        snprintf(name, length, _T("%s"), tmps.toLocal8Bit().constData());
 }
 
+void OSD::lock_vm(void)
+{
+       if(parent_thread != NULL) { 
+               if(!parent_thread->now_debugging()) VMSemaphore->acquire(1);
+       } else {
+               VMSemaphore->acquire(1);
+       }
+}
+
+void OSD::unlock_vm(void)
+{
+       if(parent_thread != NULL) { 
+               if(!parent_thread->now_debugging()) VMSemaphore->release(1);
+       } else {
+               VMSemaphore->release(1);
+       }
+}
+
+void OSD::force_unlock_vm(void)
+{
+       if(parent_thread == NULL) {
+               while(VMSemaphore->available() < 1) VMSemaphore->release(1);
+               return;
+       }
+       if(parent_thread->now_debugging()) return;
+       while(VMSemaphore->available() < 1) VMSemaphore->release(1);
+}
index 1ac3aa6..75587a2 100644 (file)
@@ -167,7 +167,7 @@ protected:
        
        // console
        FILE *hStdIn, *hStdOut;
-       FIFO *osd_console_input;
+       char console_string[128];
        bool osd_console_opened;
        // input
        void initialize_input();
@@ -574,20 +574,18 @@ public:
        void set_parent_thread(EmuThreadClass *parent);
        EmuThreadClass *get_parent_handler();
        void set_draw_thread(DrawThreadClass *handler);
-       void lock_vm(void){
-               VMSemaphore->acquire(1);
-       }
-       void unlock_vm(void){
-               VMSemaphore->release(1);
-       }
-       void force_unlock_vm(void){
-               while(VMSemaphore->available() < 1) VMSemaphore->release(1);
-       }
+       _TCHAR *console_input_string(void);
+       void clear_console_input_string(void);
+       void lock_vm(void);
+       void unlock_vm(void);
+       void force_unlock_vm(void);
+
 public slots:
 #ifdef USE_AUTO_KEY
        void set_auto_key_string(QByteArray);
 #endif
        void do_write_inputdata(QString s);
+       void do_set_input_string(QString s);
        void do_close_debugger_console();
        void do_close_debugger_thread();
        
@@ -597,6 +595,7 @@ signals:
        int sig_close_window(void);
        int sig_resize_vm_screen(QImage *, int, int);
        int sig_put_string_debugger(QString);
+       int sig_console_input_string(QString);
        int sig_debugger_finished();
 };
 QT_END_NAMESPACE
index 1a896aa..02ec1ed 100644 (file)
@@ -22,29 +22,37 @@ extern EMU *emu;
 void OSD::do_write_inputdata(QString s)
 {
        int i;
-       QByteArray p = s.toUtf8();
-       //printf("%s\n", p.constData());
-       //lock_vm();
-       for(i = 0; i < p.length(); i++){
-               osd_console_input->write(p.at(i));
-               printf("%c", p.at(i));
-       }
-       //unlock_vm();
+       emit sig_console_input_string(s);
 }
 
-void OSD::open_console(_TCHAR* title)
+void OSD::do_set_input_string(QString s)
+{
+       memset(console_string, 0x00, sizeof(console_string));
+       strncpy(console_string, s.toLocal8Bit().constData(), sizeof(console_string) - 1);
+}
+
+_TCHAR *OSD::console_input_string(void)
+{
+       if(strlen(console_string) <= 0) return NULL;
+       return console_string;
+}
+
+void OSD::clear_console_input_string(void)
 {
+       memset(console_string, 0x00, sizeof(console_string));
+}
 
-       if(osd_console_opened || (osd_console_input != NULL)) return;
+void OSD::open_console(_TCHAR* title)
+{
+       if(osd_console_opened) return;
+       memset(console_string, 0x00, sizeof(console_string));
        osd_console_opened = true;
-       osd_console_input = new FIFO(65536);
+       
 }
 
 void OSD::close_console()
 {
-       osd_console_input->release();
-       delete osd_console_input;
-       osd_console_input = NULL;
+       memset(console_string, 0x00, sizeof(console_string));
        osd_console_opened = false;
 }
 
@@ -73,13 +81,7 @@ void OSD::write_console(_TCHAR* buffer, unsigned int length)
 int OSD::read_console_input(_TCHAR* buffer)
 {
        int i;
-       int count;
-       //lock_vm();
-       count = osd_console_input->count();
-       for(i = 0; i < count; i++) {
-               buffer[i] = (_TCHAR)osd_console_input->read();
-       }
-       //unlock_vm();
+       int count = 0;
        return count;
 }
 
@@ -91,6 +93,9 @@ void OSD::do_close_debugger_console()
 void OSD::do_close_debugger_thread()
 {
 #if defined(USE_DEBUGGER)
-       emu->close_debugger();
+       //if(emu->debugger_thread_param.request_terminate == true) {
+               emit sig_debugger_finished();
+               //}
+       //emu->close_debugger();
 #endif 
 }