OSDN Git Service

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