OSDN Git Service

[VM][General] Merge Upstream 20180530.
[csp-qt/common_source_project-fm7.git] / source / src / vm / debugger.h
index d422dba..0ca4172 100644 (file)
 #ifndef _DEBUGGER_H_
 #define _DEBUGGER_H_
 
-#include "vm.h"
-#include "../emu.h"
+//#include "vm.h"
+//#include "../emu.h"
 #include "device.h"
 
-#ifdef USE_DEBUGGER
+//#ifdef USE_DEBUGGER
 
 #define MAX_BREAK_POINTS       8
+#define MAX_COMMAND_LENGTH     64
+#define MAX_COMMAND_HISTORY    32
+#define MAX_CPU_TRACE          1024
 
 typedef struct {
        struct {
-               uint32 addr, mask;
+               uint32_t addr, mask;
                int status;     // 0 = none, 1 = enabled, other = disabled
+               bool check_point;
        } table[MAX_BREAK_POINTS], stored[MAX_BREAK_POINTS];
-       bool hit;
-       uint32 hit_addr;
+       bool hit, restart;
+       uint32_t hit_addr;
 } break_point_t;
 
 class DEBUGGER : public DEVICE
@@ -32,170 +36,183 @@ class DEBUGGER : public DEVICE
 private:
        DEVICE *d_mem, *d_io;
        
-       void check_mem_break_points(break_point_t *bp, uint32 addr, int length)
+       void check_mem_break_points(break_point_t *bp, uint32_t addr, int length)
        {
                for(int i = 0; i < MAX_BREAK_POINTS; i++) {
                        if(bp->table[i].status == 1) {
                                if(addr >= bp->table[i].addr && addr < bp->table[i].addr + length) {
                                        bp->hit = now_suspended = true;
                                        bp->hit_addr = bp->table[i].addr;
+                                       bp->restart = bp->table[i].check_point;
                                        break;
                                }
                        }
                }
        }
-       void check_io_break_points(break_point_t *bp, uint32 addr)
+       void check_io_break_points(break_point_t *bp, uint32_t addr)
        {
                for(int i = 0; i < MAX_BREAK_POINTS; i++) {
                        if(bp->table[i].status == 1) {
                                if((addr & bp->table[i].mask) == (bp->table[i].addr & bp->table[i].mask)) {
                                        bp->hit = now_suspended = true;
                                        bp->hit_addr = addr;
+                                       bp->restart = bp->table[i].check_point;
                                        break;
                                }
                        }
                }
        }
 public:
-       DEBUGGER(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
+       DEBUGGER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
        {
                memset(&bp, 0, sizeof(bp));
                memset(&rbp, 0, sizeof(rbp));
                memset(&wbp, 0, sizeof(wbp));
                memset(&ibp, 0, sizeof(ibp));
                memset(&obp, 0, sizeof(obp));
+               first_symbol = last_symbol = NULL;
                my_tcscpy_s(file_path, _MAX_PATH, _T("debug.bin"));
-               now_debugging = now_going = now_suspended = false;
+               now_debugging = now_going = now_suspended = now_waiting = false;
+               memset(history, 0, sizeof(history));
+               history_ptr = 0;
+               memset(cpu_trace, 0xff, sizeof(cpu_trace));
+               prev_cpu_trace = 0xffffffff;
+               cpu_trace_ptr = 0;
+               set_device_name(_T("Debugger"));
        }
        ~DEBUGGER() {}
        
        // common functions
-       void write_data8(uint32 addr, uint32 data)
+       void release()
+       {
+               release_symbols();
+       }
+       void write_data8(uint32_t addr, uint32_t data)
        {
                check_mem_break_points(&wbp, addr, 1);
                d_mem->write_data8(addr, data);
        }
-       uint32 read_data8(uint32 addr)
+       uint32_t read_data8(uint32_t addr)
        {
                check_mem_break_points(&rbp, addr, 1);
                return d_mem->read_data8(addr);
        }
-       void write_data16(uint32 addr, uint32 data)
+       void write_data16(uint32_t addr, uint32_t data)
        {
                check_mem_break_points(&wbp, addr, 2);
                d_mem->write_data16(addr, data);
        }
-       uint32 read_data16(uint32 addr)
+       uint32_t read_data16(uint32_t addr)
        {
                check_mem_break_points(&rbp, addr, 2);
                return d_mem->read_data16(addr);
        }
-       void write_data32(uint32 addr, uint32 data)
+       void write_data32(uint32_t addr, uint32_t data)
        {
                check_mem_break_points(&wbp, addr, 4);
                d_mem->write_data32(addr, data);
        }
-       uint32 read_data32(uint32 addr)
+       uint32_t read_data32(uint32_t addr)
        {
                check_mem_break_points(&rbp, addr, 4);
                return d_mem->read_data32(addr);
        }
-       void write_data8w(uint32 addr, uint32 data, int* wait)
+       void write_data8w(uint32_t addr, uint32_t data, int* wait)
        {
                check_mem_break_points(&wbp, addr, 1);
                d_mem->write_data8w(addr, data, wait);
        }
-       uint32 read_data8w(uint32 addr, int* wait)
+       uint32_t read_data8w(uint32_t addr, int* wait)
        {
                check_mem_break_points(&rbp, addr, 1);
                return d_mem->read_data8w(addr, wait);
        }
-       void write_data16w(uint32 addr, uint32 data, int* wait)
+       void write_data16w(uint32_t addr, uint32_t data, int* wait)
        {
                check_mem_break_points(&wbp, addr, 2);
                d_mem->write_data16w(addr, data, wait);
        }
-       uint32 read_data16w(uint32 addr, int* wait)
+       uint32_t read_data16w(uint32_t addr, int* wait)
        {
                check_mem_break_points(&rbp, addr, 2);
                return d_mem->read_data16w(addr, wait);
        }
-       void write_data32w(uint32 addr, uint32 data, int* wait)
+       void write_data32w(uint32_t addr, uint32_t data, int* wait)
        {
                check_mem_break_points(&wbp, addr, 4);
                d_mem->write_data32w(addr, data, wait);
        }
-       uint32 read_data32w(uint32 addr, int* wait)
+       uint32_t read_data32w(uint32_t addr, int* wait)
        {
                check_mem_break_points(&rbp, addr, 4);
                return d_mem->read_data32w(addr, wait);
        }
-       uint32 fetch_op(uint32 addr, int *wait)
+       uint32_t fetch_op(uint32_t addr, int *wait)
        {
                check_mem_break_points(&rbp, addr, 1);
                return d_mem->fetch_op(addr, wait);
        }
-       void write_io8(uint32 addr, uint32 data)
+       void write_io8(uint32_t addr, uint32_t data)
        {
                check_io_break_points(&obp, addr);
                d_io->write_io8(addr, data);
        }
-       uint32 read_io8(uint32 addr)
+       uint32_t read_io8(uint32_t addr)
        {
                check_io_break_points(&ibp, addr);
                return d_io->read_io8(addr);
        }
-       void write_io16(uint32 addr, uint32 data)
+       void write_io16(uint32_t addr, uint32_t data)
        {
                check_io_break_points(&obp, addr);
                d_io->write_io16(addr, data);
        }
-       uint32 read_io16(uint32 addr)
+       uint32_t read_io16(uint32_t addr)
        {
                check_io_break_points(&ibp, addr);
                return d_io->read_io16(addr);
        }
-       void write_io32(uint32 addr, uint32 data)
+       void write_io32(uint32_t addr, uint32_t data)
        {
                check_io_break_points(&obp, addr);
                d_io->write_io32(addr, data);
        }
-       uint32 read_io32(uint32 addr)
+       uint32_t read_io32(uint32_t addr)
        {
                check_io_break_points(&ibp, addr);
                return d_io->read_io32(addr);
        }
-       void write_io8w(uint32 addr, uint32 data, int* wait)
+       void write_io8w(uint32_t addr, uint32_t data, int* wait)
        {
                check_io_break_points(&obp, addr);
                d_io->write_io8w(addr, data, wait);
        }
-       uint32 read_io8w(uint32 addr, int* wait)
+       uint32_t read_io8w(uint32_t addr, int* wait)
        {
                check_io_break_points(&ibp, addr);
                return d_io->read_io8w(addr, wait);
        }
-       void write_io16w(uint32 addr, uint32 data, int* wait)
+       void write_io16w(uint32_t addr, uint32_t data, int* wait)
        {
                check_io_break_points(&obp, addr);
                d_io->write_io16w(addr, data, wait);
        }
-       uint32 read_io16w(uint32 addr, int* wait)
+       uint32_t read_io16w(uint32_t addr, int* wait)
        {
                check_io_break_points(&ibp, addr);
                return d_io->read_io16w(addr, wait);
        }
-       void write_io32w(uint32 addr, uint32 data, int* wait)
+       void write_io32w(uint32_t addr, uint32_t data, int* wait)
        {
                check_io_break_points(&obp, addr);
                d_io->write_io32w(addr, data, wait);
        }
-       uint32 read_io32w(uint32 addr, int* wait)
+       uint32_t read_io32w(uint32_t addr, int* wait)
        {
                check_io_break_points(&ibp, addr);
                return d_io->read_io32w(addr, wait);
        }
-       
+
        // unique functions
        void set_context_mem(DEVICE* device)
        {
@@ -205,7 +222,7 @@ public:
        {
                d_io = device;
        }
-       void check_break_points(uint32 addr)
+       void check_break_points(uint32_t addr)
        {
                check_mem_break_points(&bp, addr, 1);
        }
@@ -234,11 +251,49 @@ public:
        {
                return (bp.hit || rbp.hit || wbp.hit || ibp.hit || obp.hit);
        }
+       void add_symbol(uint32_t addr, const _TCHAR *name)
+       {
+               symbol_t *symbol = (symbol_t *)calloc(sizeof(symbol_t), 1);
+               symbol->addr = addr;
+               symbol->name = (_TCHAR *)calloc(sizeof(_TCHAR), _tcslen(name) + 1);
+               my_tcscpy_s(symbol->name, _tcslen(name) + 1, name);
+               
+               if(first_symbol == NULL) {
+                       first_symbol = symbol;
+               } else {
+                       last_symbol->next_symbol = symbol;
+               }
+               last_symbol = symbol;
+       }
+       void release_symbols()
+       {
+               for(symbol_t* symbol = first_symbol; symbol;) {
+                       symbol_t *next_symbol = symbol->next_symbol;
+                       if(symbol->name != NULL) {
+                               free(symbol->name);
+                       }
+                       free(symbol);
+                       symbol = next_symbol;
+               }
+               first_symbol = last_symbol = NULL;
+       }
+       void add_cpu_trace(uint32_t pc)
+       {
+               if(prev_cpu_trace != pc) {
+                       cpu_trace[cpu_trace_ptr++] = prev_cpu_trace = pc;
+                       cpu_trace_ptr &= (MAX_CPU_TRACE - 1);
+               }
+       }
        break_point_t bp, rbp, wbp, ibp, obp;
+       symbol_t *first_symbol, *last_symbol;
        _TCHAR file_path[_MAX_PATH];
-       bool now_debugging, now_going, now_suspended;
+       bool now_debugging, now_going, now_suspended, now_waiting;
+       _TCHAR history[MAX_COMMAND_HISTORY][MAX_COMMAND_LENGTH + 1];
+       int history_ptr;
+       uint32_t cpu_trace[MAX_CPU_TRACE], prev_cpu_trace;
+       int cpu_trace_ptr;
 };
 
-#endif
+//#endif
 #endif