#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
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)
{
{
d_io = device;
}
- void check_break_points(uint32 addr)
+ void check_break_points(uint32_t addr)
{
check_mem_break_points(&bp, addr, 1);
}
{
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