Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
716 | lvd | 1 | #include "std.h" |
2 | |||
3 | #include "emul.h" |
||
4 | #include "vars.h" |
||
5 | #include "draw.h" |
||
6 | #include "dx.h" |
||
7 | #include "debug.h" |
||
8 | #include "dbgpaint.h" |
||
9 | #include "dbgreg.h" |
||
10 | #include "dbgtrace.h" |
||
11 | #include "dbgmem.h" |
||
12 | #include "dbgoth.h" |
||
13 | #include "dbglabls.h" |
||
14 | #include "dbgbpx.h" |
||
15 | |||
16 | #include "util.h" |
||
17 | |||
18 | #ifdef MOD_MONITOR |
||
19 | |||
20 | unsigned char trace_labels; |
||
21 | |||
22 | unsigned show_scrshot; |
||
23 | unsigned user_watches[3] = { 0x4000, 0x8000, 0xC000 }; |
||
24 | |||
25 | unsigned mem_sz = 8; |
||
26 | unsigned mem_disk, mem_track, mem_max; |
||
27 | unsigned char mem_ascii; |
||
28 | unsigned char mem_dump; |
||
29 | unsigned char editor = ED_MEM; |
||
30 | |||
31 | unsigned regs_curs; |
||
32 | unsigned dbg_extport; |
||
33 | unsigned char dgb_extval; // extended memory port like 1FFD or DFFD |
||
34 | |||
35 | unsigned ripper; // ripper mode (none/read/write) |
||
36 | |||
37 | DBGWND activedbg = WNDTRACE; |
||
38 | |||
39 | void debugscr(); |
||
40 | unsigned find1dlg(unsigned start); |
||
41 | unsigned find2dlg(unsigned start); |
||
42 | |||
43 | /* |
||
44 | #include "dbgpaint.cpp" |
||
45 | #include "dbglabls.cpp" |
||
46 | #include "z80asm.cpp" |
||
47 | #include "dbgreg.cpp" |
||
48 | #include "dbgmem.cpp" |
||
49 | #include "dbgtrace.cpp" |
||
50 | #include "dbgrwdlg.cpp" |
||
51 | #include "dbgcmd.cpp" |
||
52 | #include "dbgbpx.cpp" |
||
53 | #include "dbgoth.cpp" |
||
54 | */ |
||
55 | |||
56 | void debugscr() |
||
57 | { |
||
58 | memset(txtscr, BACKGR_CH, sizeof txtscr/2); |
||
59 | memset(txtscr+sizeof txtscr/2, BACKGR, sizeof txtscr/2); |
||
60 | nfr = 0; |
||
61 | |||
62 | showregs(); |
||
63 | showtrace(); |
||
64 | showmem(); |
||
65 | showwatch(); |
||
66 | showstack(); |
||
67 | show_ay(); |
||
68 | showbanks(); |
||
69 | showports(); |
||
70 | showdos(); |
||
71 | |||
72 | #if 1 |
||
73 | show_time(); |
||
74 | #else |
||
75 | tprint(copy_x, copy_y, "\x1A", 0x9C); |
||
76 | tprint(copy_x+1, copy_y, "UnrealSpeccy " VERS_STRING, 0x9E); |
||
77 | tprint(copy_x+20, copy_y, "by SMT", 0x9D); |
||
78 | tprint(copy_x+26, copy_y, "\x1B", 0x9C); |
||
79 | frame(copy_x, copy_y, 27, 1, 0x0A); |
||
80 | #endif |
||
81 | } |
||
82 | |||
83 | void handle_mouse() |
||
84 | { |
||
85 | Z80 &cpu = CpuMgr.Cpu(); |
||
86 | unsigned mx = ((mousepos & 0xFFFF)-temp.gx)/8, |
||
87 | my = (((mousepos >> 16) & 0x7FFF)-temp.gy)/16; |
||
88 | if (my >= trace_y && my < trace_y+trace_size && mx >= trace_x && mx < trace_x+32) |
||
89 | { |
||
90 | needclr++; activedbg = WNDTRACE; |
||
91 | cpu.trace_curs = cpu.trpc[my - trace_y]; |
||
92 | if (mx - trace_x < cs[1][0]) cpu.trace_mode = 0; |
||
93 | else if (mx - trace_x < cs[2][0]) cpu.trace_mode = 1; |
||
94 | else cpu.trace_mode = 2; |
||
95 | } |
||
96 | if (my >= mem_y && my < mem_y+mem_size && mx >= mem_x && mx < mem_x+37) |
||
97 | { |
||
98 | needclr++; activedbg = WNDMEM; |
||
99 | unsigned dx = mx-mem_x; |
||
100 | if (mem_dump) |
||
101 | { |
||
102 | if (dx >= 5) |
||
103 | cpu.mem_curs = cpu.mem_top + (dx-5) + (my-mem_y)*32; |
||
104 | } |
||
105 | else |
||
106 | { |
||
107 | unsigned mem_se = (dx-5)%3; |
||
108 | if (dx >= 29) cpu.mem_curs = cpu.mem_top + (dx-29) + (my-mem_y)*8, mem_ascii=1; |
||
109 | if (dx >= 5 && mem_se != 2 && dx < 29) |
||
110 | cpu.mem_curs = cpu.mem_top + (dx-5)/3 + (my-mem_y)*8, |
||
111 | cpu.mem_second = mem_se, mem_ascii=0; |
||
112 | } |
||
113 | } |
||
114 | if (mx >= regs_x && my >= regs_y && mx < regs_x+32 && my < regs_y+4) { |
||
115 | needclr++; activedbg = WNDREGS; |
||
116 | for (unsigned i = 0; i < regs_layout_count; i++) { |
||
117 | unsigned delta = 1; |
||
118 | if (regs_layout[i].width == 16) delta = 4; |
||
119 | if (regs_layout[i].width == 8) delta = 2; |
||
120 | if (my-regs_y == regs_layout[i].y && mx-regs_x-regs_layout[i].x < delta) regs_curs = i; |
||
121 | } |
||
122 | } |
||
123 | if (mousepos & 0x80000000) { // right-click |
||
124 | enum { IDM_BPX=1, IDM_SOME_OTHER }; |
||
125 | HMENU menu = CreatePopupMenu(); |
||
126 | if (activedbg == WNDTRACE) { |
||
127 | AppendMenu(menu, MF_STRING, IDM_BPX, "breakpoint"); |
||
128 | } else { |
||
129 | AppendMenu(menu, MF_STRING, 0, "I don't know"); |
||
130 | AppendMenu(menu, MF_STRING, 0, "what to place"); |
||
131 | AppendMenu(menu, MF_STRING, 0, "to menu, so"); |
||
132 | AppendMenu(menu, MF_STRING, 0, "No Stuff Here"); |
||
133 | } |
||
134 | int cmd = TrackPopupMenu(menu, TPM_RETURNCMD | TPM_NONOTIFY | TPM_LEFTALIGN | TPM_TOPALIGN, |
||
135 | (mousepos & 0xFFFF) + temp.client.left, |
||
136 | ((mousepos>>16) & 0x7FFF) + temp.client.top, 0, wnd, 0); |
||
137 | DestroyMenu(menu); |
||
138 | if (cmd == IDM_BPX) cbpx(); |
||
139 | //if (cmd == IDM_SOME_OTHER) some_other(); |
||
140 | //needclr++; |
||
141 | } |
||
142 | mousepos = 0; |
||
143 | } |
||
144 | |||
145 | void TCpuMgr::CopyToPrev() |
||
146 | { |
||
147 | for(unsigned i = 0; i < Count; i++) |
||
148 | PrevCpus[i] = *Cpus[i]; |
||
149 | } |
||
150 | |||
151 | /* ------------------------------------------------------------- */ |
||
152 | void debug(Z80 *cpu) |
||
153 | { |
||
154 | OnEnterGui(); |
||
155 | temp.mon_scale = temp.scale; |
||
156 | temp.scale = 1; |
||
157 | temp.rflags = RF_MONITOR; |
||
158 | needclr = 1; |
||
159 | dbgbreak = 1; |
||
160 | set_video(); |
||
161 | |||
162 | CpuMgr.SetCurrentCpu(cpu->GetIdx()); |
||
163 | TZ80State *prevcpu = &CpuMgr.PrevCpu(cpu->GetIdx()); |
||
164 | cpu->trace_curs = cpu->pc; |
||
165 | cpu->dbg_stopsp = cpu->dbg_stophere = -1; |
||
166 | cpu->dbg_loop_r1 = 0, cpu->dbg_loop_r2 = 0xFFFF; |
||
167 | mousepos = 0; |
||
168 | |||
169 | while(dbgbreak) // debugger event loop |
||
170 | { |
||
171 | if (trace_labels) |
||
172 | mon_labels.notify_user_labels(); |
||
173 | |||
174 | cpu = &CpuMgr.Cpu(); |
||
175 | prevcpu = &CpuMgr.PrevCpu(cpu->GetIdx()); |
||
176 | repaint_dbg: |
||
177 | cpu->trace_top &= 0xFFFF; |
||
178 | cpu->trace_curs &= 0xFFFF; |
||
179 | |||
180 | debugscr(); |
||
181 | if (cpu->trace_curs < cpu->trace_top || cpu->trace_curs >= cpu->trpc[trace_size] || asmii==-1) |
||
182 | { |
||
183 | cpu->trace_top = cpu->trace_curs; |
||
184 | debugscr(); |
||
185 | } |
||
186 | |||
187 | debugflip(); |
||
188 | |||
189 | sleep: |
||
190 | while(!dispatch(0)) |
||
191 | { |
||
192 | if (mousepos) |
||
193 | handle_mouse(); |
||
194 | if (needclr) |
||
195 | { |
||
196 | needclr--; |
||
197 | goto repaint_dbg; |
||
198 | } |
||
199 | Sleep(20); |
||
200 | } |
||
201 | if (activedbg == WNDREGS && dispatch_more(ac_regs)) // Обработка горячих клавиш |
||
202 | { |
||
203 | continue; |
||
204 | } |
||
205 | if (activedbg == WNDTRACE && dispatch_more(ac_trace)) // Обработка горячих клавиш |
||
206 | { |
||
207 | continue; |
||
208 | } |
||
209 | if (activedbg == WNDMEM && dispatch_more(ac_mem)) // Обработка горячих клавиш |
||
210 | { |
||
211 | continue; |
||
212 | } |
||
213 | if (activedbg == WNDREGS && dispatch_regs()) // Обработка ввода текста |
||
214 | { |
||
215 | continue; |
||
216 | } |
||
217 | if (activedbg == WNDTRACE && dispatch_trace()) // Обработка ввода текста |
||
218 | { |
||
219 | continue; |
||
220 | } |
||
221 | if (activedbg == WNDMEM && dispatch_mem()) // Обработка ввода текста |
||
222 | { |
||
223 | continue; |
||
224 | } |
||
225 | if (needclr) |
||
226 | { |
||
227 | needclr--; |
||
228 | continue; |
||
229 | } |
||
230 | goto sleep; |
||
231 | } |
||
232 | |||
233 | *prevcpu = *cpu; |
||
234 | // CpuMgr.CopyToPrev(); |
||
235 | cpu->SetLastT(); |
||
236 | temp.scale = temp.mon_scale; |
||
237 | apply_video(); |
||
238 | OnExitGui(false); |
||
239 | } |
||
240 | |||
241 | void debug_events(Z80 *cpu) |
||
242 | { |
||
243 | unsigned pc = cpu->pc & 0xFFFF; |
||
244 | unsigned char *membit = cpu->membits + pc; |
||
245 | *membit |= MEMBITS_X; |
||
246 | cpu->dbgbreak |= (*membit & MEMBITS_BPX); |
||
247 | dbgbreak |= (*membit & MEMBITS_BPX); |
||
248 | |||
249 | if (pc == cpu->dbg_stophere) |
||
250 | { |
||
251 | cpu->dbgbreak = 1; |
||
252 | dbgbreak = 1; |
||
253 | } |
||
254 | |||
255 | if ((cpu->sp & 0xFFFF) == cpu->dbg_stopsp) |
||
256 | { |
||
257 | if (pc > cpu->dbg_stophere && pc < cpu->dbg_stophere + 0x100) |
||
258 | { |
||
259 | cpu->dbgbreak = 1; |
||
260 | dbgbreak = 1; |
||
261 | } |
||
262 | if (pc < cpu->dbg_loop_r1 || pc > cpu->dbg_loop_r2) |
||
263 | { |
||
264 | cpu->dbgbreak = 1; |
||
265 | dbgbreak = 1; |
||
266 | } |
||
267 | } |
||
268 | |||
269 | if (cpu->cbpn) |
||
270 | { |
||
271 | cpu->r_low = (cpu->r_low & 0x7F) + cpu->r_hi; |
||
272 | for (unsigned i = 0; i < cpu->cbpn; i++) |
||
273 | { |
||
274 | if (calc(cpu, cpu->cbp[i])) |
||
275 | { |
||
276 | cpu->dbgbreak = 1; |
||
277 | dbgbreak = 1; |
||
278 | } |
||
279 | } |
||
280 | } |
||
281 | |||
282 | brk_port_in = brk_port_out = -1; // reset only when breakpoints active |
||
283 | |||
284 | if (cpu->dbgbreak) |
||
285 | debug(cpu); |
||
286 | } |
||
287 | |||
288 | #endif // MOD_MONITOR |
||
289 | |||
290 | unsigned char isbrk(const Z80 &cpu) // is there breakpoints active or any other reason to use debug z80 loop? |
||
291 | { |
||
292 | #ifndef MOD_DEBUGCORE |
||
293 | return 0; |
||
294 | #else |
||
295 | |||
296 | #ifdef MOD_MEMBAND_LED |
||
297 | if (conf.led.memband & 0x80000000) |
||
298 | return 1; |
||
299 | #endif |
||
300 | |||
301 | if (conf.mem_model == MM_PROFSCORP) |
||
302 | return 1; // breakpoint on read ROM switches ROM bank |
||
303 | |||
304 | #ifdef MOD_MONITOR |
||
305 | if (cpu.cbpn) |
||
306 | return 1; |
||
307 | unsigned char res = 0; |
||
308 | for (int i = 0; i < 0x10000; i++) |
||
309 | res |= cpu.membits[i]; |
||
310 | return (res & (MEMBITS_BPR | MEMBITS_BPW | MEMBITS_BPX)); |
||
311 | #endif |
||
312 | |||
313 | #endif |
||
314 | } |