OSDN Git Service

a7906a93c4eb9f7a87e8a6152d76c75fd934de6a
[csp-qt/common_source_project-fm7.git] / source / src / vm / debugger.h
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2014.09.02-
6
7         [ debugger ]
8 */
9
10 #ifndef _DEBUGGER_H_
11 #define _DEBUGGER_H_
12
13 #include "vm.h"
14 #include "../emu.h"
15 #include "device.h"
16 #if defined(_USE_QT)
17 #include <SDL2/SDL.h>
18
19 #define Sleep(n) SDL_Delay(n)
20 #endif
21
22 #ifdef USE_DEBUGGER
23
24 #define MAX_BREAK_POINTS        8
25
26 typedef struct {
27         struct {
28                 uint32 addr, mask;
29                 int status;     // 0 = none, 1 = enabled, other = disabled
30         } table[MAX_BREAK_POINTS], stored[MAX_BREAK_POINTS];
31         bool hit;
32         uint32 hit_addr;
33 } break_point_t;
34
35 class DEBUGGER : public DEVICE
36 {
37 private:
38         DEVICE *d_mem, *d_io;
39         
40         void check_mem_break_points(break_point_t *bp, uint32 addr, int length)
41         {
42                 for(int i = 0; i < MAX_BREAK_POINTS; i++) {
43                         if(bp->table[i].status == 1) {
44                                 if(addr >= bp->table[i].addr && addr < bp->table[i].addr + length) {
45                                         bp->hit = now_suspended = true;
46                                         bp->hit_addr = bp->table[i].addr;
47                                         break;
48                                 }
49                         }
50                 }
51         }
52         void check_io_break_points(break_point_t *bp, uint32 addr)
53         {
54                 for(int i = 0; i < MAX_BREAK_POINTS; i++) {
55                         if(bp->table[i].status == 1) {
56                                 if((addr & bp->table[i].mask) == (bp->table[i].addr & bp->table[i].mask)) {
57                                         bp->hit = now_suspended = true;
58                                         bp->hit_addr = addr;
59                                         break;
60                                 }
61                         }
62                 }
63         }
64 public:
65         DEBUGGER(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
66         {
67                 memset(&bp, 0, sizeof(bp));
68                 memset(&rbp, 0, sizeof(rbp));
69                 memset(&wbp, 0, sizeof(wbp));
70                 memset(&ibp, 0, sizeof(ibp));
71                 memset(&obp, 0, sizeof(obp));
72                 _tcscpy_s(file_path, _MAX_PATH, _T("debug.bin"));
73                 _tcscpy_s(text_path, _MAX_PATH, _T("disasm.txt"));
74                 now_debugging = now_going = now_suspended = false;
75         }
76         ~DEBUGGER() {}
77         
78         // common functions
79         void write_data8(uint32 addr, uint32 data)
80         {
81                 check_mem_break_points(&wbp, addr, 1);
82                 d_mem->write_data8(addr, data);
83         }
84         uint32 read_data8(uint32 addr)
85         {
86                 check_mem_break_points(&rbp, addr, 1);
87                 return d_mem->read_data8(addr);
88         }
89         void write_data16(uint32 addr, uint32 data)
90         {
91                 check_mem_break_points(&wbp, addr, 2);
92                 d_mem->write_data16(addr, data);
93         }
94         uint32 read_data16(uint32 addr)
95         {
96                 check_mem_break_points(&rbp, addr, 2);
97                 return d_mem->read_data16(addr);
98         }
99         void write_data32(uint32 addr, uint32 data)
100         {
101                 check_mem_break_points(&wbp, addr, 4);
102                 d_mem->write_data32(addr, data);
103         }
104         uint32 read_data32(uint32 addr)
105         {
106                 check_mem_break_points(&rbp, addr, 4);
107                 return d_mem->read_data32(addr);
108         }
109         void write_data8w(uint32 addr, uint32 data, int* wait)
110         {
111                 check_mem_break_points(&wbp, addr, 1);
112                 d_mem->write_data8w(addr, data, wait);
113         }
114         uint32 read_data8w(uint32 addr, int* wait)
115         {
116                 check_mem_break_points(&rbp, addr, 1);
117                 return d_mem->read_data8w(addr, wait);
118         }
119         void write_data16w(uint32 addr, uint32 data, int* wait)
120         {
121                 check_mem_break_points(&wbp, addr, 2);
122                 d_mem->write_data16w(addr, data, wait);
123         }
124         uint32 read_data16w(uint32 addr, int* wait)
125         {
126                 check_mem_break_points(&rbp, addr, 2);
127                 return d_mem->read_data16w(addr, wait);
128         }
129         void write_data32w(uint32 addr, uint32 data, int* wait)
130         {
131                 check_mem_break_points(&wbp, addr, 4);
132                 d_mem->write_data32w(addr, data, wait);
133         }
134         uint32 read_data32w(uint32 addr, int* wait)
135         {
136                 check_mem_break_points(&rbp, addr, 4);
137                 return d_mem->read_data32w(addr, wait);
138         }
139         uint32 fetch_op(uint32 addr, int *wait)
140         {
141                 check_mem_break_points(&rbp, addr, 1);
142                 return d_mem->fetch_op(addr, wait);
143         }
144         void write_io8(uint32 addr, uint32 data)
145         {
146                 check_io_break_points(&obp, addr);
147                 d_io->write_io8(addr, data);
148         }
149         uint32 read_io8(uint32 addr)
150         {
151                 check_io_break_points(&ibp, addr);
152                 return d_io->read_io8(addr);
153         }
154         void write_io16(uint32 addr, uint32 data)
155         {
156                 check_io_break_points(&obp, addr);
157                 d_io->write_io16(addr, data);
158         }
159         uint32 read_io16(uint32 addr)
160         {
161                 check_io_break_points(&ibp, addr);
162                 return d_io->read_io16(addr);
163         }
164         void write_io32(uint32 addr, uint32 data)
165         {
166                 check_io_break_points(&obp, addr);
167                 d_io->write_io32(addr, data);
168         }
169         uint32 read_io32(uint32 addr)
170         {
171                 check_io_break_points(&ibp, addr);
172                 return d_io->read_io32(addr);
173         }
174         void write_io8w(uint32 addr, uint32 data, int* wait)
175         {
176                 check_io_break_points(&obp, addr);
177                 d_io->write_io8w(addr, data, wait);
178         }
179         uint32 read_io8w(uint32 addr, int* wait)
180         {
181                 check_io_break_points(&ibp, addr);
182                 return d_io->read_io8w(addr, wait);
183         }
184         void write_io16w(uint32 addr, uint32 data, int* wait)
185         {
186                 check_io_break_points(&obp, addr);
187                 d_io->write_io16w(addr, data, wait);
188         }
189         uint32 read_io16w(uint32 addr, int* wait)
190         {
191                 check_io_break_points(&ibp, addr);
192                 return d_io->read_io16w(addr, wait);
193         }
194         void write_io32w(uint32 addr, uint32 data, int* wait)
195         {
196                 check_io_break_points(&obp, addr);
197                 d_io->write_io32w(addr, data, wait);
198         }
199         uint32 read_io32w(uint32 addr, int* wait)
200         {
201                 check_io_break_points(&ibp, addr);
202                 return d_io->read_io32w(addr, wait);
203         }
204         
205         // unique functions
206         void set_context_mem(DEVICE* device)
207         {
208                 d_mem = device;
209         }
210         void set_context_io(DEVICE* device)
211         {
212                 d_io = device;
213         }
214         void check_break_points(uint32 addr)
215         {
216                 check_mem_break_points(&bp, addr, 1);
217         }
218         void store_break_points()
219         {
220                 memcpy( bp.stored,  bp.table, sizeof( bp.table));
221                 memcpy(rbp.stored, rbp.table, sizeof(rbp.table));
222                 memcpy(wbp.stored, wbp.table, sizeof(wbp.table));
223                 memcpy(ibp.stored, ibp.table, sizeof(ibp.table));
224                 memcpy(obp.stored, obp.table, sizeof(obp.table));
225                 memset( bp.table, 0, sizeof( bp.table));
226                 memset(rbp.table, 0, sizeof(rbp.table));
227                 memset(wbp.table, 0, sizeof(wbp.table));
228                 memset(ibp.table, 0, sizeof(ibp.table));
229                 memset(obp.table, 0, sizeof(obp.table));
230         }
231         void restore_break_points()
232         {
233                 memcpy( bp.table,  bp.stored, sizeof( bp.table));
234                 memcpy(rbp.table, rbp.stored, sizeof(rbp.table));
235                 memcpy(wbp.table, wbp.stored, sizeof(wbp.table));
236                 memcpy(ibp.table, ibp.stored, sizeof(ibp.table));
237                 memcpy(obp.table, obp.stored, sizeof(obp.table));
238         }
239         bool hit()
240         {
241                 return (bp.hit || rbp.hit || wbp.hit || ibp.hit || obp.hit);
242         }
243         break_point_t bp, rbp, wbp, ibp, obp;
244         _TCHAR file_path[_MAX_PATH];
245         _TCHAR text_path[_MAX_PATH];
246         bool now_debugging, now_going, now_suspended;
247 };
248
249 #endif
250 #endif
251