PageRenderTime 62ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/od-win32/debug_win32.cpp

https://github.com/tonioni/WinUAE
C++ | 2226 lines | 2094 code | 124 blank | 8 comment | 540 complexity | 58efe5bf0f9e616c19465022a404872f MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * WinUAE GUI debugger
  3. *
  4. * Copyright 2008 Karsten Bock
  5. * Copyright 2007 Toni Wilen
  6. *
  7. */
  8. #include "sysconfig.h"
  9. #include "sysdeps.h"
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <windows.h>
  13. #include <windowsx.h>
  14. #include <commctrl.h>
  15. #include "resource.h"
  16. #include "options.h"
  17. #include "memory.h"
  18. #include "custom.h"
  19. #include "newcpu.h"
  20. #include "cia.h"
  21. #include "disk.h"
  22. #include "debug.h"
  23. #include "identify.h"
  24. #include "savestate.h"
  25. #include "debug_win32.h"
  26. #include "win32.h"
  27. #include "registry.h"
  28. #include "win32gui.h"
  29. #include "fpp.h"
  30. #include "uae.h"
  31. static HWND hDbgWnd = 0;
  32. static HWND hOutput = 0;
  33. static HACCEL dbgaccel = 0;
  34. static HFONT udfont = 0;
  35. static HWND hedit = 0;
  36. extern int consoleopen;
  37. BOOL debuggerinitializing = FALSE;
  38. extern uae_u32 get_fpsr (void);
  39. extern void set_fpsr (uae_u32 x);
  40. static TCHAR linebreak[] = {'\r', '\n', '\0'};
  41. #define MAXLINES 250
  42. #define MAXINPUTHIST 50
  43. #define MAXPAGECONTROLS 5
  44. #define MAXPAGES 10
  45. #define CLASSNAMELENGTH 50
  46. static int inputfinished = 0;
  47. static WORD* dlgtmpl;
  48. static int reopen;
  49. struct histnode {
  50. TCHAR *command;
  51. struct histnode *prev;
  52. struct histnode *next;
  53. };
  54. static struct histnode *firsthist, *lasthist, *currhist;
  55. static int histcount;
  56. struct debuggerpage {
  57. HWND ctrl[MAXPAGECONTROLS];
  58. uae_u32 memaddr;
  59. uae_u32 dasmaddr;
  60. TCHAR addrinput[9];
  61. int selection;
  62. int init;
  63. int autoset;
  64. };
  65. static struct debuggerpage dbgpage[MAXPAGES];
  66. static int currpage, pages;
  67. static int pagetype;
  68. const TCHAR *pname[] = { _T("OUT1"), _T("OUT2"), _T("MEM1"), _T("MEM2"), _T("DASM1"), _T("DASM2"), _T("BRKPTS"), _T("MISC"), _T("CUSTOM") };
  69. static int pstatuscolor[MAXPAGES];
  70. static int dbgwnd_minx = 800, dbgwnd_miny = 600;
  71. static BOOL useinternalcmd = FALSE;
  72. static TCHAR internalcmd[MAX_LINEWIDTH + 1];
  73. static const TCHAR *markinstr[] = { _T("JMP"), _T("BT L"), _T("RTS"), _T("RTD"), _T("RTE"), _T("RTR"), 0 };
  74. static const TCHAR *ucbranch[] = { _T("BSR"), _T("JMP"), _T("JSR"), 0 };
  75. static const TCHAR *cbranch[] = { _T("B"), _T("DB"), _T("FB"), _T("FDB"), 0 };
  76. static const TCHAR *ccode[] = { _T("T "), _T("F "), _T("HI"), _T("LS"), _T("CC"), _T("CS"), _T("NE"), _T("EQ"),
  77. _T("VC"), _T("VS"), _T("PL"), _T("MI"), _T("GE"), _T("LT"), _T("GT"), _T("LE"), 0 };
  78. static void OutputCurrHistNode(HWND hWnd)
  79. {
  80. int txtlen;
  81. TCHAR *buf;
  82. if (currhist->command) {
  83. txtlen = GetWindowTextLength(hWnd);
  84. buf = xmalloc(TCHAR, txtlen + 1);
  85. GetWindowText(hWnd, buf, txtlen + 1);
  86. if (_tcscmp(buf, currhist->command)) {
  87. SetWindowText(hWnd, currhist->command);
  88. txtlen = _tcslen(currhist->command);
  89. SendMessage(hWnd, EM_SETSEL, (WPARAM)txtlen, (LPARAM)txtlen);
  90. SendMessage(hWnd, EM_SETSEL, -1, -1);
  91. }
  92. }
  93. }
  94. static void SetPrevHistNode(HWND hWnd)
  95. {
  96. if (currhist) {
  97. if (currhist->prev)
  98. currhist = currhist->prev;
  99. OutputCurrHistNode(hWnd);
  100. }
  101. else if (lasthist) {
  102. currhist = lasthist;
  103. OutputCurrHistNode(hWnd);
  104. }
  105. }
  106. static void SetNextHistNode(HWND hWnd)
  107. {
  108. if (currhist) {
  109. if (currhist->next)
  110. currhist = currhist->next;
  111. OutputCurrHistNode(hWnd);
  112. }
  113. }
  114. static void DeleteFromHistory(int count)
  115. {
  116. int i;
  117. struct histnode *tmp;
  118. for (i = 0; i < count && histcount; i++) {
  119. tmp = firsthist;
  120. firsthist = firsthist->next;
  121. if (currhist == tmp)
  122. currhist = NULL;
  123. if (lasthist == tmp)
  124. lasthist = NULL;
  125. if (firsthist)
  126. firsthist->prev = NULL;
  127. free(tmp->command);
  128. free(tmp);
  129. histcount--;
  130. }
  131. }
  132. static void AddToHistory(const TCHAR *command)
  133. {
  134. struct histnode *tmp;
  135. currhist = NULL;
  136. if (histcount > 0 && !_tcscmp(command, lasthist->command))
  137. return;
  138. else if (histcount == MAXINPUTHIST)
  139. DeleteFromHistory(1);
  140. tmp = lasthist;
  141. lasthist = xmalloc(struct histnode, 1);
  142. if (histcount == 0)
  143. firsthist = lasthist;
  144. lasthist->command = my_strdup(command);
  145. lasthist->next = NULL;
  146. lasthist->prev = tmp;
  147. if (tmp)
  148. tmp->next = lasthist;
  149. histcount++;
  150. }
  151. int GetInput (TCHAR *out, int maxlen)
  152. {
  153. HWND hInput;
  154. int chars;
  155. if (!hDbgWnd)
  156. return 0;
  157. hInput = GetDlgItem(hDbgWnd, IDC_DBG_INPUT);
  158. chars = GetWindowText(hInput, out, maxlen);
  159. if (chars == 0)
  160. return 0;
  161. WriteOutput(linebreak + 1, 2);
  162. WriteOutput(out, _tcslen(out));
  163. WriteOutput(linebreak + 1, 2);
  164. AddToHistory(out);
  165. SetWindowText(hInput, _T(""));
  166. return chars;
  167. }
  168. static int CheckLineLimit(HWND hWnd, const TCHAR *out)
  169. {
  170. TCHAR *tmp, *p;
  171. int lines_have, lines_new = 0, lastchr, txtlen, visible;
  172. tmp = (TCHAR *)out;
  173. lines_have = SendMessage(hWnd, EM_GETLINECOUNT, 0, 0);
  174. while (_tcslen(tmp) > 0 && (p = _tcschr(tmp, '\n')) > 0) {
  175. lines_new++;
  176. tmp = p + 1;
  177. }
  178. lines_new++;
  179. if (lines_new > MAXLINES)
  180. return 0;
  181. if (lines_have + lines_new > MAXLINES) {
  182. visible = IsWindowVisible(hWnd);
  183. if (visible)
  184. SendMessage(hWnd, WM_SETREDRAW, FALSE, 0);
  185. lastchr = SendMessage(hWnd, EM_LINEINDEX, lines_have + lines_new - MAXLINES, 0);
  186. SendMessage(hWnd, EM_SETSEL, 0, lastchr);
  187. SendMessage(hWnd, EM_REPLACESEL, FALSE, (LPARAM)"");
  188. txtlen = GetWindowTextLength(hWnd);
  189. SendMessage(hWnd, EM_SETSEL, (WPARAM)txtlen, (LPARAM)txtlen);
  190. SendMessage(hWnd, EM_SETSEL, -1, -1);
  191. if (visible)
  192. SendMessage(hWnd, WM_SETREDRAW, TRUE, 0);
  193. }
  194. return 1;
  195. }
  196. void WriteOutput(const TCHAR *out, int len)
  197. {
  198. int txtlen, pos = 0, count, index, leave = 0;
  199. TCHAR *buf = 0, *p, *tmp;
  200. if (!hOutput || !_tcscmp(out, _T(">")) || len == 0)
  201. return;
  202. if (!CheckLineLimit(hOutput, out))
  203. return;
  204. tmp = (TCHAR *)out;
  205. for(;;) {
  206. p = _tcschr(tmp, '\n');
  207. if (p) {
  208. pos = p - tmp + 1;
  209. if (pos > (MAX_LINEWIDTH + 1))
  210. pos = MAX_LINEWIDTH + 1;
  211. buf = xcalloc(TCHAR, pos + 2);
  212. _tcsncpy(buf, tmp, pos - 1);
  213. _tcscat(buf, linebreak);
  214. } else if (_tcslen(tmp) == 0) {
  215. leave = 1;
  216. } else {
  217. count = SendMessage(hOutput, EM_GETLINECOUNT, 0, 0);
  218. index = SendMessage(hOutput, EM_LINEINDEX, count - 1, 0);
  219. txtlen = SendMessage(hOutput, EM_LINELENGTH, index, 0);
  220. if (_tcslen(tmp) + txtlen > MAX_LINEWIDTH) {
  221. buf = xcalloc(TCHAR, MAX_LINEWIDTH + 3 - txtlen);
  222. _tcsncpy(buf, tmp, MAX_LINEWIDTH - txtlen);
  223. _tcscat(buf, linebreak);
  224. }
  225. leave = 1;
  226. }
  227. txtlen = GetWindowTextLength(hOutput);
  228. SendMessage(hOutput, EM_SETSEL, (WPARAM)txtlen, (LPARAM)txtlen);
  229. SendMessage(hOutput, EM_REPLACESEL, FALSE, (LPARAM)(buf ? buf : tmp));
  230. if (buf) {
  231. xfree(buf);
  232. buf = 0;
  233. tmp += pos;
  234. }
  235. if (leave)
  236. return;
  237. }
  238. }
  239. static HWND ulbs_hwnd;
  240. static int ulbs_pos;
  241. static void UpdateListboxString(HWND hWnd, int pos, TCHAR *out, int mark)
  242. {
  243. int count;
  244. TCHAR text[MAX_LINEWIDTH + 1], *p;
  245. COLORREF cr;
  246. if (!IsWindowEnabled(hWnd)) {
  247. p = _tcschr(out, ':');
  248. if (p)
  249. *(p + 1) = '\0';
  250. }
  251. if (_tcslen(out) > MAX_LINEWIDTH)
  252. out[MAX_LINEWIDTH] = '\0';
  253. p = _tcschr(out, '\n');
  254. if (p)
  255. *p = '\0';
  256. cr = GetSysColor(COLOR_WINDOWTEXT);
  257. count = SendMessage(hWnd, (UINT) LB_GETCOUNT, 0, 0);
  258. if (pos < count) {
  259. memset(text, 0, MAX_LINEWIDTH + 1);
  260. SendMessage(hWnd, LB_GETTEXT, pos, (LPARAM)((LPTSTR)text));
  261. if (_tcscmp(out, text) != 0 && mark)
  262. cr = GetSysColor(COLOR_HIGHLIGHT);
  263. SendMessage(hWnd, LB_DELETESTRING, pos, 0);
  264. }
  265. SendMessage(hWnd, LB_INSERTSTRING, pos, (LPARAM)out);
  266. SendMessage(hWnd, LB_SETITEMDATA, pos, cr);
  267. }
  268. static void ULBSINIT(HWND hwnd)
  269. {
  270. ulbs_hwnd = hwnd;
  271. ulbs_pos = 0;
  272. }
  273. static void ULBS(const TCHAR *format, ...)
  274. {
  275. TCHAR buffer[MAX_LINEWIDTH + 1];
  276. va_list parms;
  277. va_start(parms, format);
  278. _vsntprintf(buffer, MAX_LINEWIDTH, format, parms);
  279. UpdateListboxString(ulbs_hwnd, ulbs_pos++, buffer, FALSE);
  280. }
  281. static void ULBST(const TCHAR *format, ...)
  282. {
  283. TCHAR buffer[MAX_LINEWIDTH + 1];
  284. va_list parms;
  285. va_start(parms, format);
  286. _vsntprintf(buffer, MAX_LINEWIDTH, format, parms);
  287. UpdateListboxString(ulbs_hwnd, ulbs_pos++, buffer, TRUE);
  288. }
  289. static int GetLBOutputLines(HWND hWnd)
  290. {
  291. int lines = 0, clientsize, itemsize;
  292. RECT rc;
  293. GetClientRect(hWnd, &rc);
  294. clientsize = rc.bottom - rc.top;
  295. itemsize = SendMessage(hWnd, LB_GETITEMHEIGHT, 0, 0);
  296. while (clientsize > itemsize) {
  297. lines ++;
  298. clientsize -= itemsize;
  299. }
  300. return lines;
  301. }
  302. static void ShowMiscCPU(HWND hwnd)
  303. {
  304. int line = 0;
  305. TCHAR out[MAX_LINEWIDTH + 1];
  306. int i;
  307. for (i = 0; m2cregs[i].regno>= 0; i++) {
  308. if (!movec_illg(m2cregs[i].regno)) {
  309. _stprintf(out, _T("%-4s %08X"), m2cregs[i].regname, val_move2c(m2cregs[i].regno));
  310. UpdateListboxString(hwnd, line++, out, TRUE);
  311. }
  312. }
  313. }
  314. static int dcustom[] = {
  315. 0x02, 0x9a, 0x9c, 0x8080, 0x8084, 0x8e, 0x90, 0x92, 0x94,
  316. 0x100, 0x102, 0x104, 0x106, 0x10c, 0
  317. };
  318. static uae_u32 gw(uae_u8 *p, int off)
  319. {
  320. return (p[off] << 8) | p[off + 1];
  321. }
  322. static void ShowCustomSmall(HWND hwnd)
  323. {
  324. int len, i, j, cnt;
  325. uae_u8 *p1, *p2, *p3, *p4;
  326. TCHAR out[MAX_LINEWIDTH + 1];
  327. p1 = p2 = save_custom (&len, 0, 1);
  328. p1 += 4; // skip chipset type
  329. for (i = 0; i < 4; i++) {
  330. p4 = p1 + 0xa0 + i * 16;
  331. p3 = save_audio (i, &len, 0);
  332. p4[0] = p3[12];
  333. p4[1] = p3[13];
  334. p4[2] = p3[14];
  335. p4[3] = p3[15];
  336. p4[4] = p3[4];
  337. p4[5] = p3[5];
  338. p4[6] = p3[8];
  339. p4[7] = p3[9];
  340. p4[8] = 0;
  341. p4[9] = p3[1];
  342. p4[10] = p3[10];
  343. p4[11] = p3[11];
  344. free (p3);
  345. }
  346. ULBSINIT(hwnd);
  347. cnt = 0;
  348. _stprintf(out, _T("CPU %d"), currprefs.cpu_model);
  349. if (currprefs.fpu_model)
  350. _stprintf (out + _tcslen(out), _T("/%d"), currprefs.fpu_model);
  351. _stprintf(out + _tcslen(out), _T(" %s"), (currprefs.chipset_mask & CSMASK_AGA) ? _T("AGA") : ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? _T("ECS") : _T("OCS")));
  352. ULBST(out);
  353. ULBST(_T("VPOS %04X (%d)"), vpos, vpos);
  354. ULBST(_T("HPOS %04X (%d)"), current_hpos(), current_hpos());
  355. for (i = 0; dcustom[i]; i++) {
  356. for (j = 0; custd[j].name; j++) {
  357. if (custd[j].adr == (dcustom[i] & 0x1fe) + 0xdff000) {
  358. if (dcustom[i] & 0x8000)
  359. ULBST(_T("%-8s %08X"), custd[j].name, (gw(p1, dcustom[i] & 0x1fe) << 16) | gw(p1, (dcustom[i] & 0x1fe) + 2));
  360. else
  361. ULBST(_T("%-8s %04X"), custd[j].name, gw(p1, dcustom[i] & 0x1fe));
  362. break;
  363. }
  364. }
  365. }
  366. free (p2);
  367. }
  368. static void ShowMisc(void)
  369. {
  370. int line = 0;
  371. HWND hMisc;
  372. int len, i;
  373. uae_u8 *p, *p2;
  374. hMisc = GetDlgItem(hDbgWnd, IDC_DBG_MISC);
  375. ULBSINIT(hMisc);
  376. for (i = 0; i < 2; i++) {
  377. p = p2 = save_cia (i, &len, NULL);
  378. ULBS(_T(""));
  379. ULBS(_T("CIA %c:"), i == 1 ? 'B' : 'A');
  380. ULBS(_T(""));
  381. ULBS(_T("PRA %02X PRB %02X"), p[0], p[1]);
  382. ULBS(_T("DRA %02X DRB %02X"), p[2], p[3]);
  383. ULBS(_T("CRA %02X CRB %02X ICR %02X IM %02X"),
  384. p[14], p[15], p[13], p[16]);
  385. ULBS(_T("TA %04X (%04X) TB %04X (%04X)"),
  386. (p[5] << 8) | p[4], (p[18] << 8) | p[17],
  387. (p[7] << 8) | p[6], (p[20] << 8) | p[19]);
  388. ULBS(_T("TOD %06X (%06X) ALARM %06X %c%c"),
  389. (p[10] << 16) | (p[ 9] << 8) | p[ 8],
  390. (p[23] << 16) | (p[22] << 8) | p[21],
  391. (p[26] << 16) | (p[25] << 8) | p[24],
  392. (p[27] & 1) ? 'L' : ' ', (p[27] & 2) ? ' ' : 'S');
  393. free(p2);
  394. }
  395. for (i = 0; i < 4; i++) {
  396. p = p2 = save_disk (i, &len, NULL, false);
  397. ULBS(_T(""));
  398. ULBS(_T("Drive DF%d: (%s)"), i, (p[4] & 2) ? "disabled" : "enabled");
  399. ULBS(_T("ID %08X Motor %s Cylinder %2d MFMPOS %d"),
  400. (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3],
  401. (p[4] & 1) ? _T("On") : _T("Off"),
  402. p[5], (p[8] << 24) | (p[9] << 16) | (p[10] << 8) | p[11]);
  403. if (p[16])
  404. ULBS(_T("'%s'"), p + 16);
  405. else
  406. ULBS(_T("Drive is empty"));
  407. free(p2);
  408. }
  409. p = p2 = save_floppy (&len, NULL);
  410. ULBS(_T(""));
  411. ULBS(_T("Disk controller:"));
  412. ULBS(_T(""));
  413. ULBS(_T("Shift register: Data=%04X Shift=%d. DMA=%d,%d"), (p[0] << 8) | p[1], p[2], p[3], p[5]);
  414. free (p2);
  415. }
  416. static void ShowCustom(void)
  417. {
  418. int len, i, j, end;
  419. uae_u8 *p1, *p2, *p3, *p4;
  420. ULBSINIT(GetDlgItem(hDbgWnd, IDC_DBG_CUSTOM));
  421. p1 = p2 = save_custom (&len, 0, 1);
  422. p1 += 4; // skip chipset type
  423. for (i = 0; i < 4; i++) {
  424. p4 = p1 + 0xa0 + i * 16;
  425. p3 = save_audio (i, &len, 0);
  426. p4[0] = p3[12];
  427. p4[1] = p3[13];
  428. p4[2] = p3[14];
  429. p4[3] = p3[15];
  430. p4[4] = p3[4];
  431. p4[5] = p3[5];
  432. p4[6] = p3[8];
  433. p4[7] = p3[9];
  434. p4[8] = 0;
  435. p4[9] = p3[1];
  436. p4[10] = p3[10];
  437. p4[11] = p3[11];
  438. free (p3);
  439. }
  440. end = 0;
  441. while (custd[end].name)
  442. end++;
  443. end++;
  444. end /= 2;
  445. for (i = 0; i < end; i++) {
  446. uae_u16 v1, v2;
  447. int addr1, addr2;
  448. j = end + i;
  449. addr1 = custd[i].adr & 0x1ff;
  450. addr2 = custd[j].adr & 0x1ff;
  451. v1 = (p1[addr1 + 0] << 8) | p1[addr1 + 1];
  452. v2 = (p1[addr2 + 0] << 8) | p1[addr2 + 1];
  453. ULBS(_T("%03.3X %-15s %04X %03X %-15s %04X"),
  454. addr1, custd[i].name, v1,
  455. addr2, custd[j].name, v2);
  456. }
  457. free (p2);
  458. }
  459. static void ShowBreakpoints(void)
  460. {
  461. HWND hBrkpts;
  462. int i, lines_old, got;
  463. TCHAR outbp[MAX_LINEWIDTH + 1], outw[50];
  464. hBrkpts = GetDlgItem(hDbgWnd, IDC_DBG_BRKPTS);
  465. ULBSINIT(hBrkpts);
  466. lines_old = SendMessage(hBrkpts, LB_GETCOUNT, 0, 0);
  467. ULBS(_T(""));
  468. ULBS(_T("Breakpoints:"));
  469. ULBS(_T(""));
  470. got = 0;
  471. for (i = 0; i < BREAKPOINT_TOTAL; i++) {
  472. if (!bpnodes[i].enabled)
  473. continue;
  474. m68k_disasm_2(outbp, sizeof outbp / sizeof (TCHAR), bpnodes[i].value1, NULL, 0, NULL, 1, NULL, NULL, 0xffffffff, 0);
  475. ULBS(outbp);
  476. got = 1;
  477. }
  478. if (!got)
  479. ULBS(_T("none"));
  480. ULBS(_T(""));
  481. ULBS(_T("Memwatch breakpoints:"));
  482. ULBS(_T(""));
  483. got = 0;
  484. for (i = 0; i < MEMWATCH_TOTAL; i++) {
  485. if (mwnodes[i].size == 0)
  486. continue;
  487. memwatch_dump2(outw, sizeof outw / sizeof (TCHAR), i);
  488. ULBS(outw);
  489. got = 1;
  490. }
  491. if (!got)
  492. ULBS(_T("none"));
  493. for (i = ulbs_pos; i < lines_old; i++)
  494. SendMessage(hBrkpts, LB_DELETESTRING, ulbs_pos, 0);
  495. }
  496. static void ShowMem(int offset)
  497. {
  498. uae_u32 addr;
  499. int i, lines_old, lines_new;
  500. TCHAR out[MAX_LINEWIDTH + 1];
  501. HWND hMemory;
  502. dbgpage[currpage].memaddr += offset;
  503. addr = dbgpage[currpage].memaddr;
  504. if (currpage == 0)
  505. hMemory = GetDlgItem(hDbgWnd, IDC_DBG_MEM2);
  506. else
  507. hMemory = GetDlgItem(hDbgWnd, IDC_DBG_MEM);
  508. lines_old = SendMessage(hMemory, LB_GETCOUNT, 0, 0);
  509. lines_new = GetLBOutputLines(hMemory);
  510. for (i = 0; i < lines_new; i++) {
  511. addr = dumpmem2(addr, out, sizeof(out));
  512. UpdateListboxString(hMemory, i, out, FALSE);
  513. }
  514. for (i = lines_new; i < lines_old; i++) {
  515. SendMessage(hMemory, LB_DELETESTRING, lines_new, 0);
  516. }
  517. SendMessage(hMemory, LB_SETTOPINDEX, 0, 0);
  518. }
  519. static int GetPrevAddr(uae_u32 addr, uae_u32 *prevaddr)
  520. {
  521. uae_u32 dasmaddr, next;
  522. *prevaddr = addr;
  523. dasmaddr = addr - 20;
  524. while (dasmaddr < addr) {
  525. next = dasmaddr + 2;
  526. m68k_disasm_2(NULL, 0, dasmaddr, NULL, 0, &next, 1, NULL, NULL, 0xffffffff, 0);
  527. if (next == addr) {
  528. *prevaddr = dasmaddr;
  529. return 1;
  530. }
  531. dasmaddr = next;
  532. }
  533. return 0;
  534. }
  535. static void ShowDasm(int direction)
  536. {
  537. uae_u32 addr = 0, prev;
  538. int i, lines_old, lines_new;
  539. TCHAR out[MAX_LINEWIDTH + 1];
  540. HWND hDasm;
  541. if (currpage == 0)
  542. hDasm = GetDlgItem(hDbgWnd, IDC_DBG_DASM2);
  543. else
  544. hDasm = GetDlgItem(hDbgWnd, IDC_DBG_DASM);
  545. if (!dbgpage[currpage].init) {
  546. addr = m68k_getpc ();
  547. dbgpage[currpage].init = 1;
  548. }
  549. else if (dbgpage[currpage].autoset == 1 && direction == 0) {
  550. addr = m68k_getpc ();
  551. }
  552. else
  553. addr = dbgpage[currpage].dasmaddr;
  554. if (direction > 0) {
  555. m68k_disasm_2(NULL, 0, addr, NULL, 0, &addr, 1, NULL, NULL, 0xffffffff, 0);
  556. if (!addr || addr < dbgpage[currpage].dasmaddr)
  557. addr = dbgpage[currpage].dasmaddr;
  558. }
  559. else if (direction < 0 && addr > 0) {
  560. if (GetPrevAddr(addr, &prev))
  561. addr = prev;
  562. else
  563. addr -= 2;
  564. }
  565. dbgpage[currpage].dasmaddr = addr;
  566. lines_old = SendMessage(hDasm, LB_GETCOUNT, 0, 0);
  567. lines_new = GetLBOutputLines(hDasm);
  568. for (i = 0; i < lines_new; i++) {
  569. m68k_disasm_2(out, sizeof out / sizeof (TCHAR), addr, NULL, 0, &addr, 1, NULL, NULL, 0xffffffff, 0);
  570. if (addr > dbgpage[currpage].dasmaddr)
  571. UpdateListboxString(hDasm, i, out, FALSE);
  572. else
  573. UpdateListboxString(hDasm, i, _T(""), FALSE);
  574. }
  575. for (i = lines_new; i < lines_old; i++) {
  576. SendMessage(hDasm, LB_DELETESTRING, lines_new, 0);
  577. }
  578. SendMessage(hDasm, LB_SETTOPINDEX, 0, 0);
  579. }
  580. static void SetMemToPC(void)
  581. {
  582. int i, id;
  583. dbgpage[currpage].dasmaddr = m68k_getpc ();
  584. _stprintf(dbgpage[currpage].addrinput, _T("%08X"), dbgpage[currpage].dasmaddr);
  585. for (i = 0; i < MAXPAGECONTROLS; i++) {
  586. id = GetDlgCtrlID(dbgpage[currpage].ctrl[i]);
  587. if (id == IDC_DBG_MEMINPUT)
  588. SetWindowText(dbgpage[currpage].ctrl[i], dbgpage[currpage].addrinput);
  589. }
  590. ShowDasm(0);
  591. }
  592. static void ShowPage(int index, int force)
  593. {
  594. int i, id;
  595. HWND hwnd;
  596. if (index >= pages || ((index == currpage) && !force))
  597. return;
  598. if (currpage >= 0) {
  599. pstatuscolor[currpage] = (currpage < 2 && index > 1) ? COLOR_WINDOWTEXT : COLOR_GRAYTEXT;
  600. if (index < 2)
  601. pstatuscolor[index == 0 ? 1 : 0] = COLOR_GRAYTEXT;
  602. for (i = 0; i < MAXPAGECONTROLS; i++) {
  603. if (dbgpage[currpage].ctrl[i]) {
  604. id = GetDlgCtrlID(dbgpage[currpage].ctrl[i]);
  605. if (id == IDC_DBG_MEMINPUT)
  606. GetWindowText(dbgpage[currpage].ctrl[i], dbgpage[currpage].addrinput, 9);
  607. if (index != currpage)
  608. ShowWindow(dbgpage[currpage].ctrl[i], SW_HIDE);
  609. }
  610. }
  611. }
  612. pagetype = 0;
  613. currpage = index;
  614. for (i = 0; i < MAXPAGECONTROLS; i++) {
  615. if (dbgpage[index].ctrl[i]) {
  616. id = GetDlgCtrlID(dbgpage[index].ctrl[i]);
  617. if (id == IDC_DBG_OUTPUT1 || id == IDC_DBG_OUTPUT2) {
  618. hOutput = dbgpage[index].ctrl[i];
  619. } else if (id == IDC_DBG_MEM || id == IDC_DBG_MEM2) {
  620. ShowMem(0);
  621. pagetype = id;
  622. } else if (id == IDC_DBG_DASM) {
  623. ShowDasm(0);
  624. pagetype = id;
  625. } else if (id == IDC_DBG_DASM2) {
  626. ShowDasm(0);
  627. }
  628. else if (id == IDC_DBG_MEMINPUT) {
  629. SetWindowText(dbgpage[index].ctrl[i], dbgpage[index].addrinput);
  630. } else if (id == IDC_DBG_BRKPTS) {
  631. ShowBreakpoints();
  632. } else if (id == IDC_DBG_MISC) {
  633. ShowMisc();
  634. } else if (id == IDC_DBG_CUSTOM) {
  635. ShowCustom();
  636. } else if (id == IDC_DBG_AUTOSET) {
  637. SendMessage(dbgpage[index].ctrl[i], BM_SETCHECK, (WPARAM)dbgpage[index].autoset ? BST_CHECKED : BST_UNCHECKED, (LPARAM)0);
  638. }
  639. ShowWindow(dbgpage[index].ctrl[i], SW_SHOW);
  640. }
  641. }
  642. pstatuscolor[currpage] = COLOR_HIGHLIGHT;
  643. hwnd = GetDlgItem(hDbgWnd, IDC_DBG_STATUS);
  644. RedrawWindow(hwnd, 0, 0, RDW_INVALIDATE);
  645. }
  646. static void AddPage(int *iddata)
  647. {
  648. int i;
  649. if (pages >= MAXPAGES)
  650. return;
  651. memset(&dbgpage[pages], 0, sizeof(struct debuggerpage));
  652. for (i = 0; iddata[i] > 0; i++) {
  653. dbgpage[pages].ctrl[i] = GetDlgItem(hDbgWnd, iddata[i]);
  654. ShowWindow(dbgpage[pages].ctrl[i], SW_HIDE);
  655. }
  656. if (pages == 0)
  657. dbgpage[pages].autoset = 1;
  658. else
  659. dbgpage[pages].autoset = 0;
  660. pages++;
  661. }
  662. static int GetTextSize(HWND hWnd, TCHAR *text, int width)
  663. {
  664. HDC hdc;
  665. TEXTMETRIC tm;
  666. HFONT hfont, hfontold;
  667. hdc = GetDC(hWnd);
  668. hfont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0);
  669. hfontold = (HFONT)SelectObject(hdc, hfont);
  670. GetTextMetrics(hdc, &tm);
  671. SelectObject(hdc, hfontold);
  672. ReleaseDC(hWnd, hdc);
  673. if (!width)
  674. return tm.tmHeight + tm.tmExternalLeading;
  675. else if (text)
  676. return tm.tmMaxCharWidth * _tcslen(text);
  677. return 0;
  678. }
  679. static void InitPages(void)
  680. {
  681. int i, parts[MAXPAGES], width, pwidth = 0;
  682. HWND hwnd;
  683. int dpage[][MAXPAGECONTROLS + 1] = {
  684. { IDC_DBG_OUTPUT1, IDC_DBG_DASM2, IDC_DBG_MEM2, -1 },
  685. { IDC_DBG_OUTPUT2, -1 },
  686. { IDC_DBG_MEM, IDC_DBG_MEMINPUT, -1 },
  687. { IDC_DBG_MEM, IDC_DBG_MEMINPUT, -1 },
  688. { IDC_DBG_DASM, IDC_DBG_MEMINPUT, IDC_DBG_MEMTOPC, IDC_DBG_AUTOSET, -1 },
  689. { IDC_DBG_DASM, IDC_DBG_MEMINPUT, IDC_DBG_MEMTOPC, IDC_DBG_AUTOSET, -1 },
  690. { IDC_DBG_BRKPTS, -1 },
  691. { IDC_DBG_MISC, -1 },
  692. { IDC_DBG_CUSTOM, -1 }
  693. };
  694. pages = 0;
  695. for (i = 0; i < (sizeof(dpage) / sizeof(dpage[0])); i++)
  696. AddPage(dpage[i]);
  697. memset(parts, 0, MAXPAGES * sizeof(int));
  698. width = GetTextSize(hDbgWnd, _T("12345678"), TRUE); // longest pagename + 2
  699. for (i = 0; i < pages; i++) {
  700. pwidth += width;
  701. parts[i] = pwidth;
  702. }
  703. hwnd = GetDlgItem(hDbgWnd, IDC_DBG_STATUS);
  704. SendMessage(hwnd, SB_SETPARTS, (WPARAM)pages, (LPARAM)parts);
  705. for (i = 0; i < pages; i++) {
  706. SendMessage(hwnd, SB_SETTEXT, i | SBT_OWNERDRAW, 0);
  707. pstatuscolor[i] = COLOR_GRAYTEXT;
  708. }
  709. }
  710. static LRESULT CALLBACK InputProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  711. {
  712. WNDPROC oldproc;
  713. switch (message) {
  714. case WM_CHAR:
  715. if (!debugger_active)
  716. return 0;
  717. break;
  718. case WM_KEYUP:
  719. if (!debugger_active)
  720. return 0;
  721. switch (wParam) {
  722. case VK_RETURN:
  723. inputfinished = 1;
  724. break;
  725. case VK_UP:
  726. SetPrevHistNode(hWnd);
  727. return 0;
  728. case VK_DOWN:
  729. SetNextHistNode(hWnd);
  730. return 0;
  731. }
  732. break;
  733. }
  734. oldproc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  735. return CallWindowProc(oldproc, hWnd, message, wParam, lParam);
  736. }
  737. static LRESULT CALLBACK MemInputProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  738. {
  739. HANDLE hdata;
  740. LPWSTR lptstr;
  741. TCHAR allowed[] = _T("1234567890abcdefABCDEF");
  742. int ok = 1;
  743. TCHAR addrstr[12];
  744. uae_u32 addr;
  745. WNDPROC oldproc;
  746. switch (message) {
  747. case WM_CHAR:
  748. switch (wParam) {
  749. case VK_BACK:
  750. case VK_CANCEL: //ctrl+c
  751. case VK_FINAL: //ctrl+x
  752. case 0x16: //ctrl+v
  753. break;
  754. default:
  755. if (!debugger_active || !_tcschr(allowed, wParam))
  756. return 0;
  757. break;
  758. }
  759. break;
  760. case WM_PASTE:
  761. if (!OpenClipboard(NULL))
  762. return TRUE;
  763. hdata = GetClipboardData(CF_UNICODETEXT);
  764. if (hdata) {
  765. lptstr = (LPWSTR)GlobalLock(hdata);
  766. if (lptstr) {
  767. if (_tcsspn(lptstr, allowed) != _tcslen(lptstr))
  768. ok = 0;
  769. GlobalUnlock(hdata);
  770. }
  771. }
  772. CloseClipboard();
  773. if (!ok)
  774. return 0;
  775. break;
  776. case WM_KEYUP:
  777. if (!debugger_active)
  778. return 0;
  779. switch (wParam) {
  780. case VK_RETURN:
  781. _stprintf(addrstr, _T("0x"));
  782. GetWindowText(hWnd, addrstr + 2, 9);
  783. if (addrstr[2] != 0) {
  784. addr = _tcstoul(addrstr, NULL, 0);
  785. if (pagetype == IDC_DBG_MEM || pagetype == IDC_DBG_MEM2) {
  786. dbgpage[currpage].memaddr = addr;
  787. ShowMem(0);
  788. }
  789. else if (pagetype == IDC_DBG_DASM) {
  790. if (dbgpage[currpage].autoset)
  791. dbgpage[currpage].autoset = 2;
  792. dbgpage[currpage].dasmaddr = addr;
  793. ShowDasm(0);
  794. }
  795. }
  796. return 0;
  797. }
  798. break;
  799. }
  800. oldproc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  801. return CallWindowProc(oldproc, hWnd, message, wParam, lParam);
  802. }
  803. static INT_PTR CALLBACK AddrInputDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  804. {
  805. switch(msg)
  806. {
  807. case WM_DESTROY:
  808. PostQuitMessage (0);
  809. return TRUE;
  810. case WM_CLOSE:
  811. EndDialog(hDlg, 0);
  812. return TRUE;
  813. case WM_INITDIALOG:
  814. {
  815. RECT r;
  816. WNDPROC oldproc;
  817. DWORD msgpos = GetMessagePos();
  818. HWND hwnd = GetDlgItem(hDlg, IDC_DBG_MEMINPUT2);
  819. SendMessage(hwnd, EM_LIMITTEXT, 8, 0);
  820. oldproc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)MemInputProc);
  821. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);
  822. GetWindowRect(hDlg, &r);
  823. r.right -= r.left;
  824. r.bottom -= r.top;
  825. r.left = GET_X_LPARAM(msgpos) - r.right / 2;
  826. r.top = GET_Y_LPARAM(msgpos) - r.bottom / 2;
  827. MoveWindow(hDlg, r.left, r.top, r.right, r.bottom, FALSE);
  828. ShowWindow(hDlg, SW_SHOWNORMAL);
  829. SetFocus(GetDlgItem(hDlg, IDC_DBG_MEMINPUT2));
  830. return TRUE;
  831. }
  832. case WM_COMMAND:
  833. switch (LOWORD(wParam)) {
  834. case IDOK:
  835. {
  836. TCHAR addrstr[11] = { '0', 'x', '\0' };
  837. SendMessage(GetDlgItem(hDlg, IDC_DBG_MEMINPUT2), WM_GETTEXT, 9, (LPARAM)(addrstr + 2));
  838. if (addrstr[2] != 0) {
  839. uae_u32 addr = _tcstoul(addrstr, NULL, 0);
  840. if (dbgpage[currpage].selection == IDC_DBG_MEM || dbgpage[currpage].selection == IDC_DBG_MEM2) {
  841. dbgpage[currpage].memaddr = addr;
  842. ShowMem(0);
  843. }
  844. else {
  845. if (dbgpage[currpage].autoset)
  846. dbgpage[currpage].autoset = 2;
  847. dbgpage[currpage].dasmaddr = addr;
  848. ShowDasm(0);
  849. }
  850. }
  851. EndDialog(hDlg, 1);
  852. return TRUE;
  853. }
  854. case IDCANCEL:
  855. EndDialog(hDlg, 0);
  856. return TRUE;
  857. }
  858. break;
  859. }
  860. return FALSE;
  861. }
  862. static void CopyListboxText(HWND hwnd, BOOL all)
  863. {
  864. HANDLE hdata;
  865. LPWSTR lptstr;
  866. int i, count, start, end, size = 0;
  867. if (!OpenClipboard(hwnd))
  868. return;
  869. EmptyClipboard();
  870. if ((count = SendMessage(hwnd, LB_GETCOUNT, 0, 0)) < 1)
  871. return;
  872. if (all) {
  873. start = 0;
  874. end = count;
  875. }
  876. else {
  877. int id = GetDlgCtrlID(hwnd);
  878. start = dbgpage[currpage].selection;
  879. end = start + 1;
  880. }
  881. for (i = start; i < end; i++)
  882. size += (SendMessage(hwnd, LB_GETTEXTLEN, i, 0) + 2);
  883. size++;
  884. hdata = GlobalAlloc(GMEM_MOVEABLE, size * sizeof (TCHAR));
  885. if (hdata) {
  886. int pos = 0;
  887. lptstr = (LPWSTR)GlobalLock(hdata);
  888. lptstr[size - 1] = '\0';
  889. for (i = start; i < end; i++) {
  890. int len = SendMessage(hwnd, LB_GETTEXTLEN, i, 0);
  891. SendMessage(hwnd, LB_GETTEXT, i, (LPARAM)lptstr);
  892. lptstr[len] = '\r';
  893. lptstr[len + 1] = '\n';
  894. lptstr += (len + 2);
  895. }
  896. GlobalUnlock(hdata);
  897. SetClipboardData(CF_UNICODETEXT, hdata);
  898. }
  899. CloseClipboard();
  900. }
  901. static void ToggleBreakpoint(HWND hwnd)
  902. {
  903. TCHAR addrstr[MAX_LINEWIDTH + 1], *ptr;
  904. int index = dbgpage[currpage].selection;
  905. SendMessage(hwnd, LB_GETTEXT, index, (LPARAM)addrstr);
  906. addrstr[8] = '\0';
  907. ptr = addrstr;
  908. console_out_f (_T("\nf %s\n"), addrstr);
  909. instruction_breakpoint(&ptr);
  910. RedrawWindow(hwnd, 0, 0, RDW_INVALIDATE);
  911. }
  912. static void DeleteBreakpoints(HWND hwnd)
  913. {
  914. TCHAR *cmd = _T("d");
  915. console_out(_T("\nfd\n"));
  916. instruction_breakpoint(&cmd);
  917. RedrawWindow(hwnd, 0, 0, RDW_INVALIDATE);
  918. }
  919. static void ignore_ws (TCHAR **c)
  920. {
  921. while (**c && _istspace(**c))
  922. (*c)++;
  923. }
  924. static void ListboxEndEdit(HWND hwnd, BOOL acceptinput)
  925. {
  926. MSG msg;
  927. TCHAR *p, *p2, txt[MAX_LINEWIDTH + 1], tmp[MAX_LINEWIDTH + 1], hexstr[11] = { '0', 'x', '\0' };
  928. if (!hedit)
  929. return;
  930. ReleaseCapture();
  931. memset(txt, 0, MAX_LINEWIDTH + 1);
  932. GetWindowText(hedit, txt, MAX_LINEWIDTH + 1);
  933. p = txt;
  934. ignore_ws(&p);
  935. if ((GetWindowTextLength(hedit) == 0) || (_tcslen(p) == 0))
  936. acceptinput = FALSE;
  937. while (PeekMessage(&msg, hedit, 0, 0, PM_REMOVE)) {
  938. TranslateMessage(&msg);
  939. DispatchMessage(&msg);
  940. }
  941. DestroyWindow(hedit);
  942. hedit = NULL;
  943. if (acceptinput) {
  944. int index = dbgpage[currpage].selection, id = GetDlgCtrlID(hwnd);
  945. if (id == IDC_DBG_DREG) {
  946. _tcsncpy(hexstr + 2, txt, 8);
  947. hexstr[10] = '\0';
  948. m68k_dreg(regs, index) = _tcstoul(hexstr, NULL, 0);
  949. }
  950. else if (id == IDC_DBG_AREG) {
  951. _tcsncpy(hexstr + 2, txt, 8);
  952. hexstr[10] = '\0';
  953. m68k_areg(regs, index) = _tcstoul(hexstr, NULL, 0);
  954. }
  955. else if (id == IDC_DBG_FPREG) {
  956. TCHAR *stopstr;
  957. double value;
  958. errno = 0;
  959. value = _tcstod(txt, &stopstr);
  960. if (_tcslen(stopstr) == 0 && errno == 0)
  961. regs.fp[index].fp = _tcstod(txt, &stopstr);
  962. }
  963. else {
  964. int bytes, i, offset = -1;
  965. uae_u8 value;
  966. uae_u32 addr;
  967. SendMessage(hwnd, LB_GETTEXT, index, (LPARAM)tmp);
  968. if (id == IDC_DBG_AMEM) {
  969. addr = m68k_areg(regs, index);
  970. offset = 0;
  971. bytes = 16;
  972. }
  973. else if (id == IDC_DBG_MEM || id == IDC_DBG_MEM2) {
  974. _tcsncpy(hexstr + 2, tmp, 8);
  975. hexstr[10] = '\0';
  976. addr = _tcstoul(hexstr, NULL, 0);
  977. offset = 9;
  978. bytes = 16;
  979. }
  980. else if (id == IDC_DBG_DASM || id == IDC_DBG_DASM2) {
  981. _tcsncpy(hexstr + 2, tmp, 8);
  982. hexstr[10] = '\0';
  983. addr = _tcstoul(hexstr, NULL, 0);
  984. bytes = 0;
  985. p = tmp + 9;
  986. while (_istxdigit(p[0]) && p[4] == ' ') {
  987. bytes += 2;
  988. p += 5;
  989. }
  990. }
  991. if (offset >= 0 && !_istxdigit(tmp[offset])) {
  992. int t = 0;
  993. do {
  994. t += 5;
  995. addr += 2;
  996. bytes -= 2;
  997. } while (!_istxdigit(tmp[offset + t]) && !_istxdigit(tmp[offset + t + 1]) && _istspace(tmp[offset + t + 4]));
  998. }
  999. p = txt;
  1000. for (i = 0; i < bytes; i++) {
  1001. ignore_ws(&p);
  1002. if (!_istxdigit(p[0]))
  1003. break;
  1004. p2 = p + 1;
  1005. ignore_ws(&p2);
  1006. if (!_istxdigit(p2[0]))
  1007. break;
  1008. hexstr[2] = p[0];
  1009. hexstr[3] = p2[0];
  1010. hexstr[4] = '\0';
  1011. value = (uae_u8)_tcstoul(hexstr, NULL, 0);
  1012. put_byte(addr, value);
  1013. p = p2 + 1;
  1014. addr++;
  1015. }
  1016. }
  1017. update_debug_info();
  1018. }
  1019. else
  1020. RedrawWindow(hwnd, 0, 0, RDW_INVALIDATE);
  1021. }
  1022. static LRESULT CALLBACK ListboxEditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1023. {
  1024. HANDLE hdata;
  1025. LPWSTR lptstr;
  1026. TCHAR allowed[] = _T("1234567890abcdefABCDEF ");
  1027. int ok = 1, id;
  1028. WNDPROC oldproc;
  1029. HWND hparent = GetParent(hWnd);
  1030. id = GetDlgCtrlID(hparent);
  1031. if (id == IDC_DBG_DREG || id == IDC_DBG_AREG)
  1032. allowed[_tcslen(allowed) - 1] = '\0'; // no space
  1033. else if (id == IDC_DBG_FPREG)
  1034. _stprintf(allowed, _T("1234567890deDE.+-"));
  1035. switch (message) {
  1036. case WM_GETDLGCODE:
  1037. return DLGC_WANTALLKEYS;
  1038. case WM_MOUSELEAVE:
  1039. {
  1040. HWND hwcapt = GetCapture();
  1041. if (!hwcapt)
  1042. SetCapture(hWnd);
  1043. break;
  1044. }
  1045. case WM_LBUTTONDOWN:
  1046. case WM_RBUTTONDOWN:
  1047. {
  1048. POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
  1049. RECT rc;
  1050. GetClientRect(hWnd, &rc);
  1051. if (!PtInRect(&rc, pt))
  1052. ListboxEndEdit(hparent, TRUE);
  1053. break;
  1054. }
  1055. case WM_CHAR:
  1056. switch (wParam) {
  1057. case VK_BACK:
  1058. case VK_CANCEL: //ctrl+c
  1059. case VK_FINAL: //ctrl+x
  1060. case 0x16: //ctrl+v
  1061. break;
  1062. case VK_ESCAPE:
  1063. ListboxEndEdit(hparent, FALSE);
  1064. return 0;
  1065. default:
  1066. if (!_tcschr(allowed, wParam))
  1067. return 0;
  1068. break;
  1069. }
  1070. break;
  1071. case WM_PASTE:
  1072. if (!OpenClipboard(NULL))
  1073. return TRUE;
  1074. hdata = GetClipboardData(CF_UNICODETEXT);
  1075. if (hdata) {
  1076. lptstr = (LPWSTR)GlobalLock(hdata);
  1077. if (lptstr) {
  1078. if (_tcsspn(lptstr, allowed) != _tcslen(lptstr))
  1079. ok = 0;
  1080. GlobalUnlock(hdata);
  1081. }
  1082. }
  1083. CloseClipboard();
  1084. if (!ok)
  1085. return 0;
  1086. break;
  1087. case WM_KEYUP:
  1088. if (wParam == VK_RETURN)
  1089. ListboxEndEdit(hparent, TRUE);
  1090. break;
  1091. }
  1092. oldproc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  1093. return CallWindowProc(oldproc, hWnd, message, wParam, lParam);
  1094. }
  1095. static void ListboxEdit(HWND hwnd, int x, int y)
  1096. {
  1097. int size, id, offset, length, index, radjust = 0;
  1098. RECT rc, ri;
  1099. HFONT hfont;
  1100. WNDPROC oldproc;
  1101. TCHAR txt[MAX_LINEWIDTH + 1], tmp[MAX_LINEWIDTH + 1];
  1102. if (!debugger_active || hedit)
  1103. return;
  1104. if (!hwnd)
  1105. hwnd = GetParent(hedit);
  1106. id = GetDlgCtrlID(hwnd);
  1107. if (id == IDC_DBG_DREG || id == IDC_DBG_AREG) {
  1108. offset = 4;
  1109. length = 0;
  1110. }
  1111. else if(id == IDC_DBG_MEM || id == IDC_DBG_MEM2) {
  1112. offset = 9;
  1113. length = 39;
  1114. }
  1115. else if (id == IDC_DBG_AMEM) {
  1116. offset = 0;
  1117. length = 39;
  1118. }
  1119. else if (id == IDC_DBG_DASM || id == IDC_DBG_DASM2) {
  1120. offset = 9;
  1121. length = 0;
  1122. }
  1123. else if (id == IDC_DBG_FPREG) {
  1124. offset = 5;
  1125. length = 0;
  1126. }
  1127. else
  1128. return;
  1129. hedit = CreateWindow(_T("Edit"), _T("Listbox Edit"), WS_BORDER | WS_CHILD, 0, 0, 1, 1, hwnd, NULL, hInst, NULL);
  1130. if (!hedit)
  1131. return;
  1132. size = GetTextSize(hwnd, NULL, 0);
  1133. index = y / size;
  1134. memset(txt, 0, MAX_LINEWIDTH + 1);
  1135. SendMessage(hwnd, LB_GETITEMRECT, (WPARAM)index, (LPARAM)&ri);
  1136. SendMessage(hwnd, LB_GETTEXT, (WPARAM)index, (LPARAM)(LPTSTR)txt);
  1137. if (id == IDC_DBG_DASM || id == IDC_DBG_DASM2) {
  1138. while (_istxdigit(txt[offset + length]) && _istspace(txt[offset + length + 4]))
  1139. length += 5;
  1140. length--;
  1141. }
  1142. if (length > 0) {
  1143. int t = 0;
  1144. if (!_istxdigit(txt[offset])) {
  1145. while (_istxdigit(txt[offset + length - t - 1]) && _istspace(txt[offset + length - t - 5]))
  1146. t += 5;
  1147. offset += length - t + 1;
  1148. length = t - 1;
  1149. }
  1150. else if (!_istxdigit(txt[offset + length - 1])) {
  1151. while (_istxdigit(txt[offset + t]) && _istspace(txt[offset + t + 4]))
  1152. t += 5;
  1153. length = t - 1;
  1154. }
  1155. if (length <= 0) {
  1156. ListboxEndEdit(hwnd, FALSE);
  1157. return;
  1158. }
  1159. _tcsncpy(tmp, txt + offset, length);
  1160. tmp[length] = '\0';
  1161. radjust = GetTextSize(hwnd, tmp, TRUE);
  1162. }
  1163. else if (id == IDC_DBG_FPREG)
  1164. length = 20;
  1165. else
  1166. length = _tcslen(txt + offset);
  1167. _tcsncpy(tmp, txt, offset);
  1168. tmp[offset] = '\0';
  1169. ri.left += GetTextSize(hwnd, tmp, TRUE);
  1170. if (radjust)
  1171. ri.right = ri.left + radjust;
  1172. InflateRect(&ri, 2, 2);
  1173. GetClientRect(hwnd, &rc);
  1174. if (ri.left < 0)
  1175. OffsetRect(&ri, 2, 0);
  1176. else if (ri.right > rc.right)
  1177. OffsetRect(&ri, -2, 0);
  1178. if (index == 0)
  1179. OffsetRect(&ri, 0, 2);
  1180. else if (ri.bottom > rc.bottom)
  1181. OffsetRect(&ri, 0, -2);
  1182. if (id == IDC_DBG_DASM || id == IDC_DBG_DASM2)
  1183. OffsetRect(&ri, 2 * size, 0);
  1184. SendMessage(hedit, EM_LIMITTEXT, length, 0);
  1185. MoveWindow(hedit, ri.left, ri.top, ri.right - ri.left, ri.bottom - ri.top, FALSE);
  1186. ShowWindow(hedit, SW_SHOWNORMAL);
  1187. oldproc = (WNDPROC)SetWindowLongPtr(hedit, GWLP_WNDPROC, (LONG_PTR)ListboxEditProc);
  1188. SetWindowLongPtr(hedit, GWLP_USERDATA, (LONG_PTR)oldproc);
  1189. hfont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
  1190. SendMessage(hedit, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
  1191. memset(txt + offset + length, 0, MAX_LINEWIDTH + 1 - offset - length);
  1192. SetWindowText(hedit, txt + offset);
  1193. SetFocus(hedit);
  1194. SetCapture(hedit);
  1195. dbgpage[currpage].selection = index;
  1196. }
  1197. static void ToggleCCRFlag(HWND hwnd, int x, int y)
  1198. {
  1199. int size = GetTextSize(hwnd, NULL, 0);
  1200. int index = y / size;
  1201. TCHAR txt[MAX_LINEWIDTH + 1];
  1202. memset(txt, 0, MAX_LINEWIDTH + 1);
  1203. SendMessage(hwnd, LB_GETTEXT, (WPARAM)index, (LPARAM)(LPTSTR)txt);
  1204. switch (txt[0]) {
  1205. case 'X':
  1206. SET_XFLG(GET_XFLG() ? 0 : 1);
  1207. break;
  1208. case 'N':
  1209. SET_NFLG(GET_NFLG() ? 0 : 1);
  1210. break;
  1211. case 'Z':
  1212. SET_ZFLG(GET_ZFLG() ? 0 : 1);
  1213. break;
  1214. case 'V':
  1215. SET_VFLG(GET_VFLG() ? 0 : 1);
  1216. break;
  1217. case 'C':
  1218. SET_CFLG(GET_CFLG() ? 0 : 1);
  1219. break;
  1220. }
  1221. update_debug_info();
  1222. }
  1223. static void set_fpsr (uae_u32 x)
  1224. {
  1225. uae_u32 dhex_nan[] ={0xffffffff, 0x7fffffff};
  1226. double *fp_nan = (double *)dhex_nan;
  1227. regs.fpsr = x;
  1228. if (x & 0x01000000) {
  1229. regs.fp_result.fp = *fp_nan;
  1230. }
  1231. else if (x & 0x04000000)
  1232. regs.fp_result.fp = 0;
  1233. else if (x & 0x08000000)
  1234. regs.fp_result.fp = -1;
  1235. else
  1236. regs.fp_result.fp = 1;
  1237. }
  1238. static void ToggleFPSRFlag(HWND hwnd, int x, int y)
  1239. {
  1240. int size = GetTextSize(hwnd, NULL, 0);
  1241. int index = y / size;
  1242. uae_u32 fpsr = fpp_get_fpsr();
  1243. fpsr ^= (0x8000000 >> index);
  1244. set_fpsr(fpsr);
  1245. update_debug_info();
  1246. }
  1247. static LRESULT CALLBACK ListboxProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1248. {
  1249. WNDPROC oldproc;
  1250. HWND hinput, hsbar;
  1251. RECT rc, r;
  1252. int i, itemheight, count, height, bottom, width, id, top;
  1253. PAINTSTRUCT ps;
  1254. DRAWITEMSTRUCT dis;
  1255. HFONT oldfont, font;
  1256. HDC hdc, compdc;
  1257. HBITMAP compbmp, oldbmp;
  1258. switch (message) {
  1259. case WM_CHAR:
  1260. if (debugger_active) {
  1261. hinput = GetDlgItem(hDbgWnd, IDC_DBG_INPUT);
  1262. SetFocus(hinput);
  1263. SendMessage(hinput, WM_CHAR, wParam, lParam);
  1264. }
  1265. return 0;
  1266. case WM_ERASEBKGND:
  1267. return 1;
  1268. case WM_SETFOCUS:
  1269. return 0;
  1270. case WM_LBUTTONDBLCLK:
  1271. if (debugger_active) {
  1272. int id = GetDlgCtrlID(hWnd);
  1273. if (id == IDC_DBG_CCR)
  1274. ToggleCCRFlag(hWnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
  1275. else if (id == IDC_DBG_FPSR)
  1276. ToggleFPSRFlag(hWnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
  1277. else
  1278. ListboxEdit(hWnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
  1279. }
  1280. return 0;
  1281. case WM_PAINT:
  1282. hdc = BeginPaint(hWnd, &ps);
  1283. GetClientRect(hWnd, &rc);
  1284. height = rc.bottom - rc.top;
  1285. width = rc.right - rc.left;
  1286. bottom = rc.bottom;
  1287. itemheight = SendMessage(hWnd, LB_GETITEMHEIGHT, 0, 0);
  1288. rc.bottom = itemheight;
  1289. count = SendMessage(hWnd, LB_GETCOUNT, 0, 0);
  1290. compdc = CreateCompatibleDC(hdc);
  1291. compbmp = CreateCompatibleBitmap(hdc, width, height);
  1292. oldbmp = (HBITMAP)SelectObject(compdc, compbmp);
  1293. font = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0);
  1294. oldfont = (HFONT)SelectObject(compdc, font);
  1295. id = GetDlgCtrlID(hWnd);
  1296. dis.CtlType = ODT_LISTBOX;
  1297. dis.CtlID = id;
  1298. dis.itemAction = 0;
  1299. dis.itemState = 0;
  1300. dis.hwndItem = hWnd;
  1301. dis.hDC = compdc;
  1302. top = SendMessage(hWnd, LB_GETTOPINDEX, 0, 0);
  1303. for (i = top; i < count && rc.top < height; i++) {
  1304. dis.itemID = i;
  1305. dis.rcItem = rc;
  1306. dis.itemData = SendMessage(hWnd, LB_GETITEMDATA, i, 0);
  1307. SendMessage(hDbgWnd, WM_DRAWITEM, id, (LPARAM)&dis);
  1308. rc.top += itemheight;
  1309. rc.bottom += itemheight;
  1310. }
  1311. rc.bottom = bottom;
  1312. if (!IsWindowEnabled(hWnd))
  1313. FillRect(compdc, &rc, GetSysColorBrush(COLOR_3DFACE));
  1314. else
  1315. FillRect(compdc, &rc, GetSysColorBrush(COLOR_WINDOW));
  1316. GetWindowRect(hWnd, &rc);
  1317. hsbar = GetDlgItem(hDbgWnd, IDC_DBG_STATUS);
  1318. GetWindowRect(hsbar, &r);
  1319. if (rc.top < r.top) { // not below status bar
  1320. if (rc.bottom > r.top) // partly visible
  1321. height -= rc.bottom - r.top;
  1322. BitBlt(hdc, 0, 0, width, height, compdc, 0, 0, SRCCOPY);
  1323. }
  1324. SelectObject(compdc, oldfont);
  1325. SelectObject(compdc, oldbmp);
  1326. DeleteObject(compbmp);
  1327. DeleteDC(compdc);
  1328. EndPaint(hWnd, &ps);
  1329. return 0;
  1330. case WM_COMMAND:
  1331. switch(LOWORD(wParam)) {
  1332. case ID_DBG_SETTOA0:
  1333. case ID_DBG_SETTOA1:
  1334. case ID_DBG_SETTOA2:
  1335. case ID_DBG_SETTOA3:
  1336. case ID_DBG_SETTOA4:
  1337. case ID_DBG_SETTOA5:
  1338. case ID_DBG_SETTOA6:
  1339. case ID_DBG_SETTOA7:
  1340. dbgpage[currpage].memaddr = m68k_areg(regs, LOWORD(wParam) - ID_DBG_SETTOA0);
  1341. ShowMem(0);
  1342. return 0;
  1343. case ID_DBG_SETTOPC:
  1344. dbgpage[currpage].dasmaddr = m68k_getpc();
  1345. ShowDasm(0);
  1346. return 0;
  1347. case ID_DBG_ENTERADDR:
  1348. dbgpage[currpage].selection = GetDlgCtrlID(hWnd);
  1349. CustomDialogBox(IDD_DBGMEMINPUT, hWnd, (DLGPROC)AddrInputDialogProc);
  1350. return 0;
  1351. case ID_DBG_COPYLBLINE:
  1352. CopyListboxText(hWnd, FALSE);
  1353. return 0;
  1354. case ID_DBG_COPYLB:
  1355. CopyListboxText(hWnd, TRUE);
  1356. return 0;
  1357. case ID_DBG_TOGGLEBP:
  1358. ToggleBreakpoint(hWnd);
  1359. return 0;
  1360. case ID_DBG_DELETEBPS:
  1361. DeleteBreakpoints(hWnd);
  1362. return 0;
  1363. }
  1364. break;
  1365. }
  1366. oldproc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  1367. return CallWindowProc(oldproc, hWnd, message, wParam, lParam);
  1368. }
  1369. static LRESULT CALLBACK EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1370. {
  1371. WNDPROC oldproc;
  1372. HWND hinput;
  1373. switch (message) {
  1374. case WM_CHAR:
  1375. if (wParam != VK_CANCEL) { // not for Ctrl-C for copying
  1376. if (debugger_active) {
  1377. hinput = GetDlgItem(hDbgWnd, IDC_DBG_INPUT);
  1378. SetFocus(hinput);
  1379. SendMessage(hinput, WM_CHAR, wParam, lParam);
  1380. }
  1381. return 0;
  1382. }
  1383. break;
  1384. }
  1385. oldproc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  1386. return CallWindowProc(oldproc, hWnd, message, wParam, lParam);
  1387. }
  1388. static void moveupdown(int dir)
  1389. {
  1390. if (pagetype == IDC_DBG_MEM || pagetype == IDC_DBG_MEM2) {
  1391. if (dir > 1 || dir < -1)
  1392. dir *= 4;
  1393. ShowMem(dir * 16);
  1394. } else if (pagetype == IDC_DBG_DASM) {
  1395. if (dir > 1 || dir < -1)
  1396. dir *= 4;
  1397. while(dir) {
  1398. ShowDasm(dir > 0 ? 1 : -1);
  1399. if (dir > 0)
  1400. dir--;
  1401. if (dir < 0)
  1402. dir++;
  1403. }
  1404. }
  1405. }
  1406. static int width_adjust, height_adjust;
  1407. static RECT dlgRect;
  1408. static void adjustitem(HWND hwnd, int x, int y, int w, int h)
  1409. {
  1410. WINDOWINFO pwi;
  1411. RECT *r;
  1412. pwi.cbSize = sizeof pwi;
  1413. GetWindowInfo(hwnd, &pwi);
  1414. r = &pwi.rcWindow;
  1415. r->bottom -= r->top;
  1416. r->right -= r->left;
  1417. r->left -= dlgRect.left;
  1418. r->top -= dlgRect.top;
  1419. r->left += x;
  1420. r->top += y;
  1421. r->right += w;
  1422. r->bottom += h;
  1423. MoveWindow(hwnd, r->left, r->top, r->right, r->bottom, TRUE);
  1424. }
  1425. static int randidx;
  1426. static BOOL CALLBACK childenumproc (HWND hwnd, LPARAM lParam)
  1427. {
  1428. int id1y[] = { IDC_DBG_OUTPUT2, IDC_DBG_MEM, IDC_DBG_DASM, IDC_DBG_BRKPTS, IDC_DBG_MISC, IDC_DBG_CUSTOM, -1 };
  1429. int id2y[] = { IDC_DBG_INPUT, IDC_DBG_HELP, IDC_DBG_STATUS, -1 };
  1430. int id3y[] = { IDC_DBG_DASM2, IDC_DBG_MEM2, IDC_DBG_OUTPUT1, -1 };
  1431. int id1x[] = { IDC_DBG_OUTPUT1, IDC_DBG_OUTPUT2, IDC_DBG_MEM, IDC_DBG_MEM2, IDC_DBG_DASM, IDC_DBG_DASM2,
  1432. IDC_DBG_AMEM, IDC_DBG_PREFETCH, IDC_DBG_INPUT, IDC_DBG_STATUS, IDC_DBG_BRKPTS, IDC_DBG_MISC, IDC_DBG_CUSTOM, -1 };
  1433. int id2x[] = { IDC_DBG_HELP, IDC_DBG_CCR, IDC_DBG_SP_VBR, IDC_DBG_MMISC,
  1434. IDC_DBG_FPREG, IDC_DBG_FPSR, IDC_DBG_MCUSTOM, IDC_DBG_MISCCPU, -1 };
  1435. int dlgid, j, count, adjust, remainder, starty;
  1436. dlgid = GetDlgCtrlID(hwnd);
  1437. j = 0;
  1438. while (id1y[j] >= 0) {
  1439. if (id1y[j] == dlgid)
  1440. adjustitem(hwnd, 0, 0, 0, height_adjust);
  1441. j++;
  1442. }
  1443. j = 0;
  1444. while (id2y[j] >= 0) {
  1445. if (id2y[j] == dlgid)
  1446. adjustitem(hwnd, 0, height_adjust, 0, 0);
  1447. j++;
  1448. }
  1449. j = 0;
  1450. count = sizeof(id3y) / sizeof(int) - 1;
  1451. adjust = height_adjust / count;
  1452. remainder = height_adjust % count;
  1453. if (randidx < 0) {
  1454. srand(time(NULL));
  1455. randidx = rand() % count;
  1456. }
  1457. while (id3y[j] >= 0) {
  1458. if (id3y[j] == dlgid) {
  1459. starty = j * adjust;
  1460. if (j < randidx)
  1461. adjustitem(hwnd, 0, starty, 0, adjust);
  1462. else if (j == randidx)
  1463. adjustitem(hwnd, 0, starty, 0, adjust + remainder);
  1464. else
  1465. adjustitem(hwnd, 0, starty + remainder, 0, adjust);
  1466. }
  1467. j++;
  1468. }
  1469. j = 0;
  1470. while (id1x[j] >= 0) {
  1471. if (id1x[j] == dlgid)
  1472. adjustitem(hwnd, 0, 0, width_adjust,0);
  1473. j++;
  1474. }
  1475. j = 0;
  1476. while (id2x[j] >= 0) {
  1477. if (id2x[j] == dlgid)
  1478. adjustitem(hwnd, width_adjust,0, 0, 0);
  1479. j++;
  1480. }
  1481. return TRUE;
  1482. }
  1483. static void AdjustDialog(HWND hDlg)
  1484. {
  1485. RECT r, r2;
  1486. WINDOWINFO pwi = { sizeof(WINDOWINFO) };
  1487. GetClientRect(hDlg, &r);
  1488. width_adjust = (r.right - r.left) - (dlgRect.right - dlgRect.left);
  1489. height_adjust = (r.bottom - r.top) - (dlgRect.bottom - dlgRect.top);
  1490. GetWindowRect(hDlg, &dlgRect);
  1491. r2.left = r2.top = r2.right = r2.bottom = 0;
  1492. GetWindowInfo(hDlg, &pwi);
  1493. AdjustWindowRectEx(&r2, pwi.dwStyle, FALSE, pwi.dwExStyle);
  1494. dlgRect.left -= r2.left;
  1495. dlgRect.top -= r2.top;
  1496. randidx = -1;
  1497. EnumChildWindows (hDlg, childenumproc, 0);
  1498. dlgRect = r;
  1499. RedrawWindow(hDlg, 0, 0, RDW_INVALIDATE);
  1500. }
  1501. static BOOL CALLBACK InitChildWindows(HWND hWnd, LPARAM lParam)
  1502. {
  1503. int i, id, enable = TRUE, items = 0;
  1504. WNDPROC newproc = NULL, oldproc;
  1505. TCHAR classname[CLASSNAMELENGTH];
  1506. WINDOWINFO pwi;
  1507. RECT *r;
  1508. id = GetDlgCtrlID(hWnd);
  1509. switch (id) {
  1510. case IDC_DBG_INPUT:
  1511. newproc = InputProc;
  1512. SendMessage(hWnd, EM_LIMITTEXT, MAX_LINEWIDTH, 0);
  1513. break;
  1514. case IDC_DBG_MEMINPUT:
  1515. newproc = MemInputProc;
  1516. SendMessage(hWnd, EM_LIMITTEXT, 8, 0);
  1517. break;
  1518. case IDC_DBG_PREFETCH:
  1519. newproc = ListboxProc;
  1520. enable = currprefs.cpu_compatible ? TRUE : FALSE;
  1521. break;
  1522. case IDC_DBG_FPREG:
  1523. case IDC_DBG_FPSR:
  1524. newproc = ListboxProc;
  1525. enable = currprefs.cpu_model < 68020 ? FALSE : TRUE;
  1526. break;
  1527. case IDC_DBG_MISCCPU:
  1528. if (currprefs.cpu_model == 68000) {
  1529. items = 4;
  1530. enable = FALSE;
  1531. }
  1532. else {
  1533. for (i = 0; m2cregs[i].regno>= 0; i++) {
  1534. if (!movec_illg(m2cregs[i].regno))
  1535. items++;
  1536. }
  1537. }
  1538. pwi.cbSize = sizeof pwi;
  1539. GetWindowInfo(hWnd, &pwi);
  1540. r = &pwi.rcClient;
  1541. r->bottom = r->top + items * GetTextSize(hWnd, NULL, FALSE);
  1542. AdjustWindowRectEx(r, pwi.dwStyle, FALSE, pwi.dwExStyle);
  1543. SetWindowPos(hWnd, 0, 0, 0, r->right - r->left, r->bottom - r->top, SWP_NOMOVE | SWP_NOZORDER);
  1544. newproc = ListboxProc;
  1545. break;
  1546. default:
  1547. if (GetClassName(hWnd, classname, CLASSNAMELENGTH)) {
  1548. if (!_tcscmp(classname, _T("ListBox")))
  1549. newproc = ListboxProc;
  1550. else if (!_tcscmp(classname, _T("Edit")))
  1551. newproc = EditProc;
  1552. }
  1553. break;
  1554. }
  1555. if (newproc) {
  1556. oldproc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)newproc);
  1557. SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)oldproc);
  1558. }
  1559. EnableWindow(hWnd, enable);
  1560. return TRUE;
  1561. }
  1562. static void step(BOOL over)
  1563. {
  1564. if (over)
  1565. _tcscpy(internalcmd, _T("z"));
  1566. else
  1567. _tcscpy(internalcmd, _T("t"));
  1568. useinternalcmd = TRUE;
  1569. inputfinished = 1;
  1570. }
  1571. static void ShowContextMenu(HWND hwnd, int x, int y)
  1572. {
  1573. POINT pt = { x, y };
  1574. HMENU hmenu, hsubmenu;
  1575. int id = GetDlgCtrlID(hwnd);
  1576. if (x == -1 || y == -1) {
  1577. DWORD msgpos = GetMessagePos();
  1578. pt.x = GET_X_LPARAM(msgpos);
  1579. pt.y = GET_Y_LPARAM(msgpos);
  1580. }
  1581. hmenu = LoadMenu(hUIDLL ? hUIDLL : hInst, MAKEINTRESOURCE(IDM_DBGCONTEXTMENU));
  1582. if (!hmenu)
  1583. return;
  1584. if (!debugger_active)
  1585. hsubmenu = GetSubMenu(hmenu, 0);
  1586. else if (id == IDC_DBG_MEM || id == IDC_DBG_MEM2)
  1587. hsubmenu = GetSubMenu(hmenu, 1);
  1588. else if (id == IDC_DBG_DASM || id == IDC_DBG_DASM2)
  1589. hsubmenu = GetSubMenu(hmenu, 2);
  1590. TrackPopupMenu(hsubmenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
  1591. DestroyMenu(hmenu);
  1592. SendMessage(hwnd, LB_SETCURSEL, -1, 0);
  1593. }
  1594. static void SelectListboxLine(HWND hwnd, int x, int y)
  1595. {
  1596. POINT pt = { x, y };
  1597. int index;
  1598. int size = GetTextSize(hwnd, NULL, 0);
  1599. int id = GetDlgCtrlID(hwnd);
  1600. if (x == -1 || y == -1) {
  1601. DWORD msgpos = GetMessagePos();
  1602. pt.x = GET_X_LPARAM(msgpos);
  1603. pt.y = GET_Y_LPARAM(msgpos);
  1604. }
  1605. ScreenToClient(hwnd, &pt);
  1606. index = pt.y / size;
  1607. SendMessage(hwnd, LB_SETCURSEL, index, 0);
  1608. dbgpage[currpage].selection = index;
  1609. }
  1610. static INT_PTR CALLBACK DebuggerProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1611. {
  1612. HWND hwnd;
  1613. static BOOL sizing = FALSE;
  1614. switch (message) {
  1615. case WM_INITDIALOG:
  1616. {
  1617. int newpos = 0;
  1618. int x, y, w, h;
  1619. RECT rw;
  1620. HFONT hfont;
  1621. LOGFONT lf;
  1622. GetWindowRect(hDlg, &rw);
  1623. dbgwnd_minx = rw.right - rw.left;
  1624. dbgwnd_miny = rw.bottom - rw.top;
  1625. GetClientRect(hDlg, &dlgRect);
  1626. newpos = 1;
  1627. if (!regqueryint (NULL, _T("DebuggerPosX"), &x))
  1628. newpos = 0;
  1629. if (!regqueryint (NULL, _T("DebuggerPosY"), &y))
  1630. newpos = 0;
  1631. if (!regqueryint (NULL, _T("DebuggerPosW"), &w))
  1632. newpos = 0;
  1633. if (!regqueryint (NULL, _T("DebuggerPosH"), &h))
  1634. newpos = 0;
  1635. if (newpos) {
  1636. RECT rc;
  1637. rc.left = x;
  1638. rc.top = y;
  1639. rc.right = x + w;
  1640. rc.bottom = y + h;
  1641. if (MonitorFromRect (&rc, MONITOR_DEFAULTTONULL) != NULL)
  1642. SetWindowPos(hDlg, 0, x, y, w, h, SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_DEFERERASE);
  1643. }
  1644. SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_APPICON)));
  1645. EnumChildWindows(hDlg, InitChildWindows, 0);
  1646. currpage = -1;
  1647. firsthist = lasthist = currhist = NULL;
  1648. histcount = 0;
  1649. inputfinished = 0;
  1650. AdjustDialog(hDlg);
  1651. hfont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0);
  1652. GetObject(hfont, sizeof(LOGFONT), &lf);
  1653. lf.lfEscapement = lf.lfOrientation = 1800;
  1654. udfont = CreateFontIndirect(&lf);
  1655. return TRUE;
  1656. }
  1657. case WM_CLOSE:
  1658. DestroyWindow(hDlg);
  1659. return TRUE;
  1660. case WM_DESTROY:
  1661. {
  1662. RECT *r;
  1663. int xoffset = 0, yoffset = 0;
  1664. WINDOWPLACEMENT wp = { sizeof(WINDOWPLACEMENT) };
  1665. MONITORINFO mi = { sizeof(MONITORINFO) };
  1666. HMONITOR hmon = MonitorFromWindow(hDlg, MONITOR_DEFAULTTONEAREST);
  1667. if (hmon && GetMonitorInfo(hmon, &mi)) {
  1668. xoffset = mi.rcWork.left - mi.rcMonitor.left;
  1669. yoffset = mi.rcWork.top - mi.rcMonitor.top;
  1670. }
  1671. if (GetWindowPlacement (hDlg, &wp)) {
  1672. r = &wp.rcNormalPosition;
  1673. r->right -= r->left;
  1674. r->bottom -= r->top;
  1675. r->left += xoffset;
  1676. r->top += yoffset;
  1677. regsetint (NULL, _T("DebuggerPosX"), r->left);
  1678. regsetint (NULL, _T("DebuggerPosY"), r->top);
  1679. regsetint (NULL, _T("DebuggerPosW"), r->right);
  1680. regsetint (NULL, _T("DebuggerPosH"), r->bottom);
  1681. regsetint (NULL, _T("DebuggerMaximized"), (IsZoomed(hDlg) || (wp.flags & WPF_RESTORETOMAXIMIZED)) ? 1 : 0);
  1682. }
  1683. hDbgWnd = 0;
  1684. PostQuitMessage(0);
  1685. DeleteFromHistory(histcount);
  1686. DeleteObject(udfont);
  1687. consoleopen = 0;
  1688. deactivate_debugger ();
  1689. return TRUE;
  1690. }
  1691. case WM_GETMINMAXINFO:
  1692. {
  1693. MINMAXINFO *mmi = (MINMAXINFO*)lParam;
  1694. mmi->ptMinTrackSize.x = dbgwnd_minx;
  1695. mmi->ptMinTrackSize.y = dbgwnd_miny;
  1696. return TRUE;
  1697. }
  1698. case WM_ENTERSIZEMOVE:
  1699. sizing = TRUE;
  1700. return FALSE;
  1701. case WM_EXITSIZEMOVE:
  1702. {
  1703. AdjustDialog(hDlg);
  1704. ShowPage(currpage, TRUE);
  1705. sizing = FALSE;
  1706. return TRUE;
  1707. }
  1708. case WM_SIZE:
  1709. {
  1710. if (!sizing && (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED)) {
  1711. AdjustDialog(hDlg);
  1712. ShowPage(currpage, TRUE);
  1713. }
  1714. return TRUE;
  1715. }
  1716. case WM_CTLCOLORSTATIC:
  1717. {
  1718. int id = GetDlgCtrlID((HWND)lParam);
  1719. if (id == IDC_DBG_OUTPUT1 || id == IDC_DBG_OUTPUT2) {
  1720. SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
  1721. return (LRESULT)GetSysColorBrush(COLOR_WINDOW);
  1722. }
  1723. return FALSE;
  1724. }
  1725. case WM_CTLCOLORLISTBOX:
  1726. hwnd = (HWND)lParam;
  1727. if (!IsWindowEnabled(hwnd)) {
  1728. SetBkColor((HDC)wParam, GetSysColor(COLOR_3DFACE));
  1729. return (LRESULT)GetSysColorBrush(COLOR_3DFACE);
  1730. }
  1731. SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
  1732. return (LRESULT)GetSysColorBrush(COLOR_WINDOW);
  1733. case WM_COMMAND:
  1734. if (!debugger_active) {
  1735. if (LOWORD(wParam) == IDC_DBG_AUTOSET && HIWORD(wParam) == BN_CLICKED)
  1736. SendMessage((HWND)lParam, BM_SETCHECK, dbgpage[currpage].autoset ? BST_CHECKED : BST_UNCHECKED, 0);
  1737. return TRUE;
  1738. }
  1739. switch (LOWORD(wParam)) {
  1740. case IDC_DBG_HELP:
  1741. {
  1742. HWND hinput;
  1743. WriteOutput(linebreak + 1, 2);
  1744. debug_help();
  1745. hinput = GetDlgItem(hDbgWnd, IDC_DBG_INPUT);
  1746. SetFocus(hinput);
  1747. return TRUE;
  1748. }
  1749. case ID_DBG_PAGE1:
  1750. case ID_DBG_PAGE2:
  1751. case ID_DBG_PAGE3:
  1752. case ID_DBG_PAGE4:
  1753. case ID_DBG_PAGE5:
  1754. case ID_DBG_PAGE6:
  1755. case ID_DBG_PAGE7:
  1756. case ID_DBG_PAGE8:
  1757. case ID_DBG_PAGE9:
  1758. // IDs have to be consecutive and in order of page order for this to work
  1759. ShowPage(LOWORD(wParam) - ID_DBG_PAGE1, FALSE);
  1760. return TRUE;
  1761. case ID_DBG_STEP_OVER:
  1762. step(TRUE);
  1763. return TRUE;
  1764. case ID_DBG_STEP_INTO:
  1765. step(FALSE);
  1766. return TRUE;
  1767. case IDC_DBG_MEMUP:
  1768. moveupdown(-1);
  1769. return TRUE;
  1770. case IDC_DBG_MEMDOWN:
  1771. moveupdown(1);
  1772. return TRUE;
  1773. case IDC_DBG_MEMUPFAST:
  1774. moveupdown(-2);
  1775. return TRUE;
  1776. case IDC_DBG_MEMDOWNFAST:
  1777. moveupdown(2);
  1778. return TRUE;
  1779. case IDC_DBG_MEMTOPC:
  1780. {
  1781. HWND hmeminput;
  1782. SetMemToPC();
  1783. hmeminput = GetDlgItem(hDbgWnd, IDC_DBG_MEMINPUT);
  1784. SetFocus(hmeminput);
  1785. return TRUE;
  1786. }
  1787. case IDC_DBG_AUTOSET:
  1788. {
  1789. if (pagetype == IDC_DBG_DASM) {
  1790. HWND hctrl;
  1791. dbgpage[currpage].autoset = 1 - dbgpage[currpage].autoset;
  1792. hctrl = GetDlgItem(hDbgWnd, IDC_DBG_AUTOSET);
  1793. SendMessage(hctrl, BM_SETCHECK, dbgpage[currpage].autoset ? BST_CHECKED : BST_UNCHECKED, 0);
  1794. hctrl = GetDlgItem(hDbgWnd, IDC_DBG_MEMINPUT);
  1795. SetFocus(hctrl);
  1796. }
  1797. return TRUE;
  1798. }
  1799. }
  1800. break;
  1801. case WM_CONTEXTMENU:
  1802. {
  1803. int id = GetDlgCtrlID((HWND)wParam);
  1804. if (id == IDC_DBG_MEM || id == IDC_DBG_MEM2 || id == IDC_DBG_DASM || id == IDC_DBG_DASM2) {
  1805. if (!hedit){
  1806. SelectListboxLine((HWND)wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
  1807. ShowContextMenu((HWND)wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
  1808. }
  1809. return TRUE;
  1810. }
  1811. break;
  1812. }
  1813. case WM_MEASUREITEM:
  1814. ((MEASUREITEMSTRUCT*)(lParam))->itemHeight = GetTextSize(hDlg, NULL, FALSE);
  1815. return TRUE;
  1816. case WM_DRAWITEM:
  1817. {
  1818. DRAWITEMSTRUCT *pdis = (DRAWITEMSTRUCT *)lParam;
  1819. HDC hdc = pdis->hDC;
  1820. RECT rc = pdis->rcItem;
  1821. TCHAR text[MAX_LINEWIDTH + 1];
  1822. uae_u32 addr;
  1823. SetBkMode(hdc, TRANSPARENT);
  1824. if (wParam == IDC_DBG_STATUS) {
  1825. SetTextColor(hdc, GetSysColor(pstatuscolor[pdis->itemID]));
  1826. DrawText(hdc, pname[pdis->itemID], _tcslen(pname[pdis->itemID]), &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  1827. return TRUE;
  1828. }
  1829. else {
  1830. if (pdis->itemID < 0) {
  1831. return TRUE;
  1832. }
  1833. memset(text, 0, MAX_LINEWIDTH + 1);
  1834. SendMessage(pdis->hwndItem, LB_GETTEXT, pdis->itemID, (LPARAM)(LPSTR)text);
  1835. if (!IsWindowEnabled(pdis->hwndItem)) {
  1836. FillRect(hdc, &rc, GetSysColorBrush(COLOR_3DFACE));
  1837. SetBkColor(hdc, GetSysColor(COLOR_3DFACE));
  1838. }
  1839. else {
  1840. FillRect(hdc, &

Large files files are truncated, but you can click here to view the full file