Advertisement
Guest User

Untitled

a guest
Oct 19th, 2017
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 151.81 KB | None | 0 0
  1. Index: include/debug.h
  2. ===================================================================
  3. --- include/debug.h (revision 3761)
  4. +++ include/debug.h (working copy)
  5. @@ -16,6 +16,19 @@
  6. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  7. */
  8.  
  9. +#ifndef DOSBOX_DEBUG_H
  10. +#define DOSBOX_DEBUG_H
  11. +
  12. +#if C_DEBUG || C_GDBSERVER
  13. +
  14. +#include <fstream>
  15. +
  16. +extern Bit16u DEBUG_dataSeg;
  17. +extern Bit32u DEBUG_dataOfs;
  18. +extern bool DEBUG_showExtend;
  19. +extern char DEBUG_curSelectorName[3];
  20. +extern bool DEBUG_exitLoop;
  21. +
  22. void DEBUG_SetupConsole(void);
  23. void DEBUG_DrawScreen(void);
  24. bool DEBUG_Breakpoint(void);
  25. @@ -25,11 +38,72 @@
  26. bool DEBUG_ExitLoop(void);
  27. void DEBUG_RefreshPage(char scroll);
  28. Bitu DEBUG_EnableDebugger(void);
  29. +Bit32u DEBUG_GetHexValue(char* str, char*& hex);
  30. +Bit32u DEBUG_GetAddress(Bit16u seg, Bit32u offset);
  31. +char* DEBUG_AnalyzeInstruction(char* inst, bool saveSelector);
  32. +bool DEBUG_GetDescriptorInfo(char* selname, char* out1, char* out2);
  33.  
  34. -extern Bitu cycle_count;
  35. -extern Bitu debugCallback;
  36. +void DEBUG_LogMCBChain(Bit16u mcb_segment);
  37. +void DEBUG_LogMCBS(void);
  38. +void DEBUG_LogGDT(void);
  39. +void DEBUG_LogLDT(void);
  40. +void DEBUG_LogIDT(void);
  41. +void DEBUG_LogPages(char* selname);
  42. +void DEBUG_LogCPUInfo(void);
  43. +void DEBUG_LogInstruction(Bit16u segValue, Bit32u eipValue, std::ofstream& out);
  44.  
  45. -#ifdef C_HEAVY_DEBUG
  46. +extern bool DEBUG_showExtend;
  47. +
  48. +extern Bitu DEBUG_cycle_count;
  49. +extern Bitu DEBUG_debugCallback;
  50. +
  51. +#if C_HEAVY_DEBUG || C_GDBSERVER
  52. +extern std::ofstream DEBUG_cpuLogFile;
  53. +extern bool DEBUG_cpuLog;
  54. +extern int DEBUG_cpuLogCounter;
  55. +extern int DEBUG_cpuLogType; // log detail
  56. +extern bool DEBUG_zeroProtect;
  57. +extern bool DEBUG_logHeavy;
  58. +
  59. bool DEBUG_HeavyIsBreakpoint(void);
  60. +void DEBUG_HeavyLogInstruction(void);
  61. void DEBUG_HeavyWriteLogInstruction(void);
  62. #endif
  63. +
  64. +#ifdef C_GDBSERVER
  65. +void DEBUG_GdbMemReadHook(Bit32u address, int width);
  66. +void DEBUG_GdbMemWriteHook(Bit32u address, int width, Bit32u value);
  67. +void DEBUG_IrqBreakpoint(Bit8u intNum);
  68. +#endif
  69. +
  70. +/********************/
  71. +/* DebugVar stuff */
  72. +/********************/
  73. +
  74. +#include <list>
  75. +#include "paging.h"
  76. +
  77. +class CDebugVar
  78. +{
  79. +public:
  80. + CDebugVar(char* _name, PhysPt _adr);
  81. +
  82. + char* GetName(void) { return name; };
  83. + PhysPt GetAdr (void) { return adr; };
  84. +
  85. +private:
  86. + PhysPt adr;
  87. + char name[16];
  88. +
  89. +public:
  90. + static void InsertVariable (char* name, PhysPt adr);
  91. + static CDebugVar* FindVar (PhysPt adr);
  92. + static void DeleteAll ();
  93. + static bool SaveVars (char* name);
  94. + static bool LoadVars (char* name);
  95. +
  96. + static std::list<CDebugVar*> varList;
  97. +};
  98. +
  99. +#endif
  100. +#endif
  101. Index: include/paging.h
  102. ===================================================================
  103. --- include/paging.h (revision 3761)
  104. +++ include/paging.h (working copy)
  105. @@ -27,6 +27,8 @@
  106. #include "mem.h"
  107. #endif
  108.  
  109. +#include "debug.h"
  110. +
  111. // disable this to reduce the size of the TLB
  112. // NOTE: does not work with the dynamic core (dynrec is fine)
  113. #define USE_FULL_TLB
  114. @@ -261,12 +263,18 @@
  115. /* Special inlined memory reading/writing */
  116.  
  117. static INLINE Bit8u mem_readb_inline(PhysPt address) {
  118. +#ifdef C_GDBSERVER
  119. + DEBUG_GdbMemReadHook(address, 1);
  120. +#endif
  121. HostPt tlb_addr=get_tlb_read(address);
  122. if (tlb_addr) return host_readb(tlb_addr+address);
  123. else return (Bit8u)(get_tlb_readhandler(address))->readb(address);
  124. }
  125.  
  126. static INLINE Bit16u mem_readw_inline(PhysPt address) {
  127. +#ifdef C_GDBSERVER
  128. + DEBUG_GdbMemReadHook(address, 1);
  129. +#endif
  130. if ((address & 0xfff)<0xfff) {
  131. HostPt tlb_addr=get_tlb_read(address);
  132. if (tlb_addr) return host_readw(tlb_addr+address);
  133. @@ -275,6 +283,9 @@
  134. }
  135.  
  136. static INLINE Bit32u mem_readd_inline(PhysPt address) {
  137. +#ifdef C_GDBSERVER
  138. + DEBUG_GdbMemReadHook(address, 1);
  139. +#endif
  140. if ((address & 0xfff)<0xffd) {
  141. HostPt tlb_addr=get_tlb_read(address);
  142. if (tlb_addr) return host_readd(tlb_addr+address);
  143. @@ -283,12 +294,18 @@
  144. }
  145.  
  146. static INLINE void mem_writeb_inline(PhysPt address,Bit8u val) {
  147. +#ifdef C_GDBSERVER
  148. + DEBUG_GdbMemWriteHook(address, 1, val);
  149. +#endif
  150. HostPt tlb_addr=get_tlb_write(address);
  151. if (tlb_addr) host_writeb(tlb_addr+address,val);
  152. else (get_tlb_writehandler(address))->writeb(address,val);
  153. }
  154.  
  155. static INLINE void mem_writew_inline(PhysPt address,Bit16u val) {
  156. +#ifdef C_GDBSERVER
  157. + DEBUG_GdbMemWriteHook(address, 2, val);
  158. +#endif
  159. if ((address & 0xfff)<0xfff) {
  160. HostPt tlb_addr=get_tlb_write(address);
  161. if (tlb_addr) host_writew(tlb_addr+address,val);
  162. @@ -297,6 +314,9 @@
  163. }
  164.  
  165. static INLINE void mem_writed_inline(PhysPt address,Bit32u val) {
  166. +#ifdef C_GDBSERVER
  167. + DEBUG_GdbMemWriteHook(address, 4, val);
  168. +#endif
  169. if ((address & 0xfff)<0xffd) {
  170. HostPt tlb_addr=get_tlb_write(address);
  171. if (tlb_addr) host_writed(tlb_addr+address,val);
  172. Index: include/logging.h
  173. ===================================================================
  174. --- include/logging.h (revision 3761)
  175. +++ include/logging.h (working copy)
  176. @@ -37,7 +37,12 @@
  177. LOG_ERROR
  178. };
  179.  
  180. -#if C_DEBUG
  181. +#if C_DEBUG || C_GDBSERVER
  182. +struct _LogGroup {
  183. + char const* front;
  184. + bool enabled;
  185. +};
  186. +
  187. class LOG
  188. {
  189. LOG_TYPES d_type;
  190. @@ -48,14 +53,14 @@
  191. d_type(type),
  192. d_severity(severity)
  193. {}
  194. - void operator() (char const* buf, ...) GCC_ATTRIBUTE(__format__(__printf__, 2, 3)); //../src/debug/debug_gui.cpp
  195. + void operator() (char const* buf, ...) GCC_ATTRIBUTE(__format__(__printf__, 2, 3)); //../src/debug/debug_log.cpp
  196.  
  197. };
  198.  
  199. void DEBUG_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2));
  200. #define LOG_MSG DEBUG_ShowMsg
  201.  
  202. -#else //C_DEBUG
  203. +#else //C_DEBUG || C_GDBSERVER
  204.  
  205. struct LOG
  206. {
  207. @@ -84,7 +89,7 @@
  208. void GFX_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2));
  209. #define LOG_MSG GFX_ShowMsg
  210.  
  211. -#endif //C_DEBUG
  212. +#endif //C_DEBUG || C_GDBSERVER
  213.  
  214.  
  215. #endif //DOSBOX_LOGGING_H
  216. Index: configure.in
  217. ===================================================================
  218. --- configure.in (revision 3761)
  219. +++ configure.in (working copy)
  220. @@ -188,13 +188,16 @@
  221. #Features to enable/disable
  222. AH_TEMPLATE(C_DEBUG,[Define to 1 to enable internal debugger, requires libcurses])
  223. AH_TEMPLATE(C_HEAVY_DEBUG,[Define to 1 to enable heavy debugging, also have to enable C_DEBUG])
  224. -AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[
  225. +AH_TEMPLATE(C_GDBSERVER,[Define to 1 to enable GNU debugger server])
  226. +AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debugger (yes, heavy or gdbserver)]),[
  227. AC_CHECK_HEADER(curses.h,have_curses_h=yes,)
  228. AC_CHECK_LIB(curses, initscr, have_curses_lib=yes, , )
  229. AC_CHECK_LIB(ncurses, initscr, have_ncurses_lib=yes, , )
  230. AC_CHECK_LIB(pdcurses, initscr, have_pdcurses_lib=yes, , )
  231.  
  232. - if test x$enable_debug = xno; then
  233. + if test x$enable_debug = xgdbserver; then
  234. + AC_DEFINE(C_GDBSERVER,1)
  235. + elif test x$enable_debug = xno; then
  236. AC_MSG_RESULT([Debugger not enabled])
  237. elif test x$have_curses_lib = xyes -a x$have_curses_h = xyes ; then
  238. LIBS="$LIBS -lcurses"
  239. Index: src/dosbox.cpp
  240. ===================================================================
  241. --- src/dosbox.cpp (revision 3761)
  242. +++ src/dosbox.cpp (working copy)
  243. @@ -140,7 +140,7 @@
  244. Bitu blah = (*CallBack_Handlers[ret])();
  245. if (GCC_UNLIKELY(blah)) return blah;
  246. }
  247. -#if C_DEBUG
  248. +#if C_DEBUG || C_GDBSERVER
  249. if (DEBUG_ExitLoop()) return 0;
  250. #endif
  251. } else {
  252. @@ -350,7 +350,7 @@
  253. Pstring = secprop->Add_path("captures",Property::Changeable::Always,"capture");
  254. Pstring->Set_help("Directory where things like wave, midi, screenshot get captured.");
  255.  
  256. -#if C_DEBUG
  257. +#if C_DEBUG || C_GDBSERVER
  258. LOG_StartUp();
  259. #endif
  260.  
  261. @@ -496,7 +496,7 @@
  262. " In that case, add 'delaysysex', for example: midiconfig=2 delaysysex\n"
  263. " See the README/Manual for more details.");
  264.  
  265. -#if C_DEBUG
  266. +#if C_DEBUG || C_GDBSERVER
  267. secprop=control->AddSection_prop("debug",&DEBUG_Init);
  268. #endif
  269.  
  270. Index: src/gui/sdlmain.cpp
  271. ===================================================================
  272. --- src/gui/sdlmain.cpp (revision 3761)
  273. +++ src/gui/sdlmain.cpp (working copy)
  274. @@ -1264,7 +1264,7 @@
  275. MAPPER_AddHandler(CaptureMouse,MK_f10,MMOD1,"capmouse","Cap Mouse");
  276. MAPPER_AddHandler(SwitchFullScreen,MK_return,MMOD2,"fullscr","Fullscreen");
  277. MAPPER_AddHandler(Restart,MK_home,MMOD1|MMOD2,"restart","Restart");
  278. -#if C_DEBUG
  279. +#if C_DEBUG || C_GDBSERVER
  280. /* Pause binds with activate-debugger */
  281. #else
  282. MAPPER_AddHandler(&PauseDOSBox, MK_pause, MMOD2, "pause", "Pause");
  283. @@ -1616,7 +1616,7 @@
  284. printf("can't find editor(s) specified at the command line.\n");
  285. exit(1);
  286. }
  287. -#if C_DEBUG
  288. +#if C_DEBUG || C_GDBSERVER
  289. extern void DEBUG_ShutDown(Section * /*sec*/);
  290. #endif
  291.  
  292. @@ -1630,7 +1630,7 @@
  293. SDL_CloseAudio();
  294. SDL_Delay(50);
  295. SDL_Quit();
  296. -#if C_DEBUG
  297. +#if C_DEBUG || C_GDBSERVER
  298. // shutdown curses
  299. DEBUG_ShutDown(NULL);
  300. #endif
  301. Index: src/dos/dos_execute.cpp
  302. ===================================================================
  303. --- src/dos/dos_execute.cpp (revision 3761)
  304. +++ src/dos/dos_execute.cpp (working copy)
  305. @@ -471,7 +471,7 @@
  306. reg_di=RealOff(sssp);
  307. reg_bp=0x91c; /* DOS internal stack begin relict */
  308. SegSet16(ds,pspseg);SegSet16(es,pspseg);
  309. -#if C_DEBUG
  310. +#if C_DEBUG
  311. /* Started from debug.com, then set breakpoint at start */
  312. DEBUG_CheckExecuteBreakpoint(RealSeg(csip),RealOff(csip));
  313. #endif
  314. Index: src/debug/poll.cpp
  315. ===================================================================
  316. --- ./src/debug/poll.cpp 1970-01-01 00:00:00 +0000
  317. +++ ./src/debug/poll.cpp 2012-03-03 10:48:02 +0000
  318. @@ -0,0 +1,595 @@
  319. +/* Emulation for poll(2)
  320. + Contributed by Paolo Bonzini.
  321. +
  322. + Copyright 2001-2003, 2006-2010 Free Software Foundation, Inc.
  323. +
  324. + This file is part of gnulib.
  325. +
  326. + This program is free software; you can redistribute it and/or modify
  327. + it under the terms of the GNU General Public License as published by
  328. + the Free Software Foundation; either version 2, or (at your option)
  329. + any later version.
  330. +
  331. + This program is distributed in the hope that it will be useful,
  332. + but WITHOUT ANY WARRANTY; without even the implied warranty of
  333. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  334. + GNU General Public License for more details.
  335. +
  336. + You should have received a copy of the GNU General Public License along
  337. + with this program; if not, write to the Free Software Foundation,
  338. + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
  339. +
  340. +/* Tell gcc not to warn about the (nfd < 0) tests, below. */
  341. +#if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
  342. +# pragma GCC diagnostic ignored "-Wtype-limits"
  343. +#endif
  344. +
  345. +#include <malloc.h>
  346. +
  347. +#include <sys/types.h>
  348. +#include "poll.h"
  349. +#include <errno.h>
  350. +#include <limits.h>
  351. +#include <assert.h>
  352. +
  353. +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  354. +# define WIN32_NATIVE
  355. +# if defined (_MSC_VER)
  356. +# define _WIN32_WINNT 0x0502
  357. +# endif
  358. +# include <winsock2.h>
  359. +# include <windows.h>
  360. +# include <io.h>
  361. +# include <stdio.h>
  362. +# include <conio.h>
  363. +#else
  364. +# include <sys/time.h>
  365. +# include <sys/socket.h>
  366. +# include <sys/select.h>
  367. +# include <unistd.h>
  368. +#endif
  369. +
  370. +#ifdef HAVE_SYS_IOCTL_H
  371. +# include <sys/ioctl.h>
  372. +#endif
  373. +#ifdef HAVE_SYS_FILIO_H
  374. +# include <sys/filio.h>
  375. +#endif
  376. +
  377. +#include <time.h>
  378. +
  379. +#ifndef INFTIM
  380. +# define INFTIM (-1)
  381. +#endif
  382. +
  383. +/* BeOS does not have MSG_PEEK. */
  384. +#ifndef MSG_PEEK
  385. +# define MSG_PEEK 0
  386. +#endif
  387. +
  388. +#ifdef WIN32_NATIVE
  389. +
  390. +#define IsConsoleHandle(h) (((long) (h) & 3) == 3)
  391. +
  392. +static BOOL
  393. +IsSocketHandle (HANDLE h)
  394. +{
  395. + WSANETWORKEVENTS ev;
  396. +
  397. + if (IsConsoleHandle (h))
  398. + return FALSE;
  399. +
  400. + /* Under Wine, it seems that getsockopt returns 0 for pipes too.
  401. + WSAEnumNetworkEvents instead distinguishes the two correctly. */
  402. + ev.lNetworkEvents = 0xDEADBEEF;
  403. + WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
  404. + return ev.lNetworkEvents != 0xDEADBEEF;
  405. +}
  406. +
  407. +/* Declare data structures for ntdll functions. */
  408. +typedef struct _FILE_PIPE_LOCAL_INFORMATION {
  409. + ULONG NamedPipeType;
  410. + ULONG NamedPipeConfiguration;
  411. + ULONG MaximumInstances;
  412. + ULONG CurrentInstances;
  413. + ULONG InboundQuota;
  414. + ULONG ReadDataAvailable;
  415. + ULONG OutboundQuota;
  416. + ULONG WriteQuotaAvailable;
  417. + ULONG NamedPipeState;
  418. + ULONG NamedPipeEnd;
  419. +} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
  420. +
  421. +typedef struct _IO_STATUS_BLOCK
  422. +{
  423. + union {
  424. + DWORD Status;
  425. + PVOID Pointer;
  426. + } u;
  427. + ULONG_PTR Information;
  428. +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
  429. +
  430. +typedef enum _FILE_INFORMATION_CLASS {
  431. + FilePipeLocalInformation = 24
  432. +} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
  433. +
  434. +typedef DWORD (WINAPI *PNtQueryInformationFile)
  435. + (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
  436. +
  437. +# ifndef PIPE_BUF
  438. +# define PIPE_BUF 512
  439. +# endif
  440. +
  441. +/* Compute revents values for file handle H. If some events cannot happen
  442. + for the handle, eliminate them from *P_SOUGHT. */
  443. +
  444. +static int
  445. +win32_compute_revents (HANDLE h, int *p_sought)
  446. +{
  447. + int i, ret, happened;
  448. + INPUT_RECORD *irbuffer;
  449. + DWORD avail, nbuffer;
  450. + BOOL bRet;
  451. + IO_STATUS_BLOCK iosb;
  452. + FILE_PIPE_LOCAL_INFORMATION fpli;
  453. + static PNtQueryInformationFile NtQueryInformationFile;
  454. + static BOOL once_only;
  455. +
  456. + switch (GetFileType (h))
  457. + {
  458. + case FILE_TYPE_PIPE:
  459. + if (!once_only)
  460. + {
  461. + NtQueryInformationFile = (PNtQueryInformationFile)
  462. + GetProcAddress (GetModuleHandle ("ntdll.dll"),
  463. + "NtQueryInformationFile");
  464. + once_only = TRUE;
  465. + }
  466. +
  467. + happened = 0;
  468. + if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
  469. + {
  470. + if (avail)
  471. + happened |= *p_sought & (POLLIN | POLLRDNORM);
  472. + }
  473. + else if (GetLastError () == ERROR_BROKEN_PIPE)
  474. + happened |= POLLHUP;
  475. +
  476. + else
  477. + {
  478. + /* It was the write-end of the pipe. Check if it is writable.
  479. + If NtQueryInformationFile fails, optimistically assume the pipe is
  480. + writable. This could happen on Win9x, where NtQueryInformationFile
  481. + is not available, or if we inherit a pipe that doesn't permit
  482. + FILE_READ_ATTRIBUTES access on the write end (I think this should
  483. + not happen since WinXP SP2; WINE seems fine too). Otherwise,
  484. + ensure that enough space is available for atomic writes. */
  485. + memset (&iosb, 0, sizeof (iosb));
  486. + memset (&fpli, 0, sizeof (fpli));
  487. +
  488. + if (!NtQueryInformationFile
  489. + || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
  490. + FilePipeLocalInformation)
  491. + || fpli.WriteQuotaAvailable >= PIPE_BUF
  492. + || (fpli.OutboundQuota < PIPE_BUF &&
  493. + fpli.WriteQuotaAvailable == fpli.OutboundQuota))
  494. + happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
  495. + }
  496. + return happened;
  497. +
  498. + case FILE_TYPE_CHAR:
  499. + ret = WaitForSingleObject (h, 0);
  500. + if (!IsConsoleHandle (h))
  501. + return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
  502. +
  503. + nbuffer = avail = 0;
  504. + bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
  505. + if (bRet)
  506. + {
  507. + /* Input buffer. */
  508. + *p_sought &= POLLIN | POLLRDNORM;
  509. + if (nbuffer == 0)
  510. + return POLLHUP;
  511. + if (!*p_sought)
  512. + return 0;
  513. +
  514. + irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
  515. + bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
  516. + if (!bRet || avail == 0)
  517. + return POLLHUP;
  518. +
  519. + for (i = 0; i < avail; i++)
  520. + if (irbuffer[i].EventType == KEY_EVENT)
  521. + return *p_sought;
  522. + return 0;
  523. + }
  524. + else
  525. + {
  526. + /* Screen buffer. */
  527. + *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
  528. + return *p_sought;
  529. + }
  530. +
  531. + default:
  532. + ret = WaitForSingleObject (h, 0);
  533. + if (ret == WAIT_OBJECT_0)
  534. + return *p_sought & ~(POLLPRI | POLLRDBAND);
  535. +
  536. + return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
  537. + }
  538. +}
  539. +
  540. +/* Convert fd_sets returned by select into revents values. */
  541. +
  542. +static int
  543. +win32_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
  544. +{
  545. + int happened = 0;
  546. +
  547. + if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
  548. + happened |= (POLLIN | POLLRDNORM) & sought;
  549. +
  550. + else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
  551. + {
  552. + int r, error;
  553. +
  554. + char data[64];
  555. + WSASetLastError (0);
  556. + r = recv (h, data, sizeof (data), MSG_PEEK);
  557. + error = WSAGetLastError ();
  558. + WSASetLastError (0);
  559. +
  560. + if (r > 0 || error == WSAENOTCONN)
  561. + happened |= (POLLIN | POLLRDNORM) & sought;
  562. +
  563. + /* Distinguish hung-up sockets from other errors. */
  564. + else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
  565. + || error == WSAECONNABORTED || error == WSAENETRESET)
  566. + happened |= POLLHUP;
  567. +
  568. + else
  569. + happened |= POLLERR;
  570. + }
  571. +
  572. + if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
  573. + happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
  574. +
  575. + if (lNetworkEvents & FD_OOB)
  576. + happened |= (POLLPRI | POLLRDBAND) & sought;
  577. +
  578. + return happened;
  579. +}
  580. +
  581. +#else /* !MinGW */
  582. +
  583. +/* Convert select(2) returned fd_sets into poll(2) revents values. */
  584. +static int
  585. +compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
  586. +{
  587. + int happened = 0;
  588. + if (FD_ISSET (fd, rfds))
  589. + {
  590. + int r;
  591. + int socket_errno;
  592. +
  593. +# if defined __MACH__ && defined __APPLE__
  594. + /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
  595. + for some kinds of descriptors. Detect if this descriptor is a
  596. + connected socket, a server socket, or something else using a
  597. + 0-byte recv, and use ioctl(2) to detect POLLHUP. */
  598. + r = recv (fd, NULL, 0, MSG_PEEK);
  599. + socket_errno = (r < 0) ? errno : 0;
  600. + if (r == 0 || socket_errno == ENOTSOCK)
  601. + ioctl (fd, FIONREAD, &r);
  602. +# else
  603. + char data[64];
  604. + r = recv (fd, data, sizeof (data), MSG_PEEK);
  605. + socket_errno = (r < 0) ? errno : 0;
  606. +# endif
  607. + if (r == 0)
  608. + happened |= POLLHUP;
  609. +
  610. + /* If the event happened on an unconnected server socket,
  611. + that's fine. */
  612. + else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
  613. + happened |= (POLLIN | POLLRDNORM) & sought;
  614. +
  615. + /* Distinguish hung-up sockets from other errors. */
  616. + else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
  617. + || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
  618. + happened |= POLLHUP;
  619. +
  620. + else
  621. + happened |= POLLERR;
  622. + }
  623. +
  624. + if (FD_ISSET (fd, wfds))
  625. + happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
  626. +
  627. + if (FD_ISSET (fd, efds))
  628. + happened |= (POLLPRI | POLLRDBAND) & sought;
  629. +
  630. + return happened;
  631. +}
  632. +#endif /* !MinGW */
  633. +
  634. +int poll (struct pollfd *pfd, nfds_t nfd, int timeout)
  635. +{
  636. +#ifndef WIN32_NATIVE
  637. + fd_set rfds, wfds, efds;
  638. + struct timeval tv;
  639. + struct timeval *ptv;
  640. + int maxfd, rc;
  641. + nfds_t i;
  642. +
  643. +# ifdef _SC_OPEN_MAX
  644. + static int sc_open_max = -1;
  645. +
  646. + if (nfd < 0
  647. + || (nfd > sc_open_max
  648. + && (sc_open_max != -1
  649. + || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
  650. + {
  651. + errno = EINVAL;
  652. + return -1;
  653. + }
  654. +# else /* !_SC_OPEN_MAX */
  655. +# ifdef OPEN_MAX
  656. + if (nfd < 0 || nfd > OPEN_MAX)
  657. + {
  658. + errno = EINVAL;
  659. + return -1;
  660. + }
  661. +# endif /* OPEN_MAX -- else, no check is needed */
  662. +# endif /* !_SC_OPEN_MAX */
  663. +
  664. + /* EFAULT is not necessary to implement, but let's do it in the
  665. + simplest case. */
  666. + if (!pfd)
  667. + {
  668. + errno = EFAULT;
  669. + return -1;
  670. + }
  671. +
  672. + /* convert timeout number into a timeval structure */
  673. + if (timeout == 0)
  674. + {
  675. + ptv = &tv;
  676. + ptv->tv_sec = 0;
  677. + ptv->tv_usec = 0;
  678. + }
  679. + else if (timeout > 0)
  680. + {
  681. + ptv = &tv;
  682. + ptv->tv_sec = timeout / 1000;
  683. + ptv->tv_usec = (timeout % 1000) * 1000;
  684. + }
  685. + else if (timeout == INFTIM)
  686. + /* wait forever */
  687. + ptv = NULL;
  688. + else
  689. + {
  690. + errno = EINVAL;
  691. + return -1;
  692. + }
  693. +
  694. + /* create fd sets and determine max fd */
  695. + maxfd = -1;
  696. + FD_ZERO (&rfds);
  697. + FD_ZERO (&wfds);
  698. + FD_ZERO (&efds);
  699. + for (i = 0; i < nfd; i++)
  700. + {
  701. + if (pfd[i].fd < 0)
  702. + continue;
  703. +
  704. + if (pfd[i].events & (POLLIN | POLLRDNORM))
  705. + FD_SET (pfd[i].fd, &rfds);
  706. +
  707. + /* see select(2): "the only exceptional condition detectable
  708. + is out-of-band data received on a socket", hence we push
  709. + POLLWRBAND events onto wfds instead of efds. */
  710. + if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
  711. + FD_SET (pfd[i].fd, &wfds);
  712. + if (pfd[i].events & (POLLPRI | POLLRDBAND))
  713. + FD_SET (pfd[i].fd, &efds);
  714. + if (pfd[i].fd >= maxfd
  715. + && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
  716. + | POLLRDNORM | POLLRDBAND
  717. + | POLLWRNORM | POLLWRBAND)))
  718. + {
  719. + maxfd = pfd[i].fd;
  720. + if (maxfd > FD_SETSIZE)
  721. + {
  722. + errno = EOVERFLOW;
  723. + return -1;
  724. + }
  725. + }
  726. + }
  727. +
  728. + /* examine fd sets */
  729. + rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
  730. + if (rc < 0)
  731. + return rc;
  732. +
  733. + /* establish results */
  734. + rc = 0;
  735. + for (i = 0; i < nfd; i++)
  736. + if (pfd[i].fd < 0)
  737. + pfd[i].revents = 0;
  738. + else
  739. + {
  740. + int happened = compute_revents (pfd[i].fd, pfd[i].events,
  741. + &rfds, &wfds, &efds);
  742. + if (happened)
  743. + {
  744. + pfd[i].revents = happened;
  745. + rc++;
  746. + }
  747. + }
  748. +
  749. + return rc;
  750. +#else
  751. + static struct timeval tv0;
  752. + static HANDLE hEvent;
  753. + WSANETWORKEVENTS ev;
  754. + HANDLE h, handle_array[FD_SETSIZE + 2];
  755. + DWORD ret, wait_timeout, nhandles;
  756. + fd_set rfds, wfds, xfds;
  757. + BOOL poll_again;
  758. + MSG msg;
  759. + int rc = 0;
  760. + nfds_t i;
  761. +
  762. + if (nfd < 0 || timeout < -1)
  763. + {
  764. + errno = EINVAL;
  765. + return -1;
  766. + }
  767. +
  768. + if (!hEvent)
  769. + hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
  770. +
  771. + handle_array[0] = hEvent;
  772. + nhandles = 1;
  773. + FD_ZERO (&rfds);
  774. + FD_ZERO (&wfds);
  775. + FD_ZERO (&xfds);
  776. +
  777. + /* Classify socket handles and create fd sets. */
  778. + for (i = 0; i < nfd; i++)
  779. + {
  780. + int sought = pfd[i].events;
  781. + pfd[i].revents = 0;
  782. + if (pfd[i].fd < 0)
  783. + continue;
  784. + if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
  785. + | POLLPRI | POLLRDBAND)))
  786. + continue;
  787. +
  788. + h = (HANDLE) _get_osfhandle (pfd[i].fd);
  789. + assert (h != NULL);
  790. + if (IsSocketHandle (h))
  791. + {
  792. + int requested = FD_CLOSE;
  793. +
  794. + /* see above; socket handles are mapped onto select. */
  795. + if (sought & (POLLIN | POLLRDNORM))
  796. + {
  797. + requested |= FD_READ | FD_ACCEPT;
  798. + FD_SET ((SOCKET) h, &rfds);
  799. + }
  800. + if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
  801. + {
  802. + requested |= FD_WRITE | FD_CONNECT;
  803. + FD_SET ((SOCKET) h, &wfds);
  804. + }
  805. + if (sought & (POLLPRI | POLLRDBAND))
  806. + {
  807. + requested |= FD_OOB;
  808. + FD_SET ((SOCKET) h, &xfds);
  809. + }
  810. +
  811. + if (requested)
  812. + WSAEventSelect ((SOCKET) h, hEvent, requested);
  813. + }
  814. + else
  815. + {
  816. + /* Poll now. If we get an event, do not poll again. Also,
  817. + screen buffer handles are waitable, and they'll block until
  818. + a character is available. win32_compute_revents eliminates
  819. + bits for the "wrong" direction. */
  820. + pfd[i].revents = win32_compute_revents (h, &sought);
  821. + if (sought)
  822. + handle_array[nhandles++] = h;
  823. + if (pfd[i].revents)
  824. + timeout = 0;
  825. + }
  826. + }
  827. +
  828. + if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
  829. + {
  830. + /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
  831. + no need to call select again. */
  832. + poll_again = FALSE;
  833. + wait_timeout = 0;
  834. + }
  835. + else
  836. + {
  837. + poll_again = TRUE;
  838. + if (timeout == INFTIM)
  839. + wait_timeout = INFINITE;
  840. + else
  841. + wait_timeout = timeout;
  842. + }
  843. +
  844. + for (;;)
  845. + {
  846. + ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
  847. + wait_timeout, QS_ALLINPUT);
  848. +
  849. + if (ret == WAIT_OBJECT_0 + nhandles)
  850. + {
  851. + /* new input of some other kind */
  852. + BOOL bRet;
  853. + while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
  854. + {
  855. + TranslateMessage (&msg);
  856. + DispatchMessage (&msg);
  857. + }
  858. + }
  859. + else
  860. + break;
  861. + }
  862. +
  863. + if (poll_again)
  864. + select (0, &rfds, &wfds, &xfds, &tv0);
  865. +
  866. + /* Place a sentinel at the end of the array. */
  867. + handle_array[nhandles] = NULL;
  868. + nhandles = 1;
  869. + for (i = 0; i < nfd; i++)
  870. + {
  871. + int happened;
  872. +
  873. + if (pfd[i].fd < 0)
  874. + continue;
  875. + if (!(pfd[i].events & (POLLIN | POLLRDNORM |
  876. + POLLOUT | POLLWRNORM | POLLWRBAND)))
  877. + continue;
  878. +
  879. + h = (HANDLE) _get_osfhandle (pfd[i].fd);
  880. + if (h != handle_array[nhandles])
  881. + {
  882. + /* It's a socket. */
  883. + WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
  884. + WSAEventSelect ((SOCKET) h, 0, 0);
  885. +
  886. + /* If we're lucky, WSAEnumNetworkEvents already provided a way
  887. + to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
  888. + if (FD_ISSET ((SOCKET) h, &rfds)
  889. + && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
  890. + ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
  891. + if (FD_ISSET ((SOCKET) h, &wfds))
  892. + ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
  893. + if (FD_ISSET ((SOCKET) h, &xfds))
  894. + ev.lNetworkEvents |= FD_OOB;
  895. +
  896. + happened = win32_compute_revents_socket ((SOCKET) h, pfd[i].events,
  897. + ev.lNetworkEvents);
  898. + }
  899. + else
  900. + {
  901. + /* Not a socket. */
  902. + int sought = pfd[i].events;
  903. + happened = win32_compute_revents (h, &sought);
  904. + nhandles++;
  905. + }
  906. +
  907. + if ((pfd[i].revents |= happened) != 0)
  908. + rc++;
  909. + }
  910. +
  911. + return rc;
  912. +#endif
  913. +}
  914. Index: src/debug/poll.h
  915. ===================================================================
  916. --- ./src/debug/poll.h 1970-01-01 00:00:00 +0000
  917. +++ ./src/debug/poll.h 2012-03-03 10:53:02 +0000
  918. @@ -0,0 +1,60 @@
  919. +/* Header for poll(2) emulation
  920. + Contributed by Paolo Bonzini.
  921. +
  922. + Copyright 2001, 2002, 2003, 2007, 2009, 2010 Free Software Foundation, Inc.
  923. +
  924. + This file is part of gnulib.
  925. +
  926. + This program is free software; you can redistribute it and/or modify
  927. + it under the terms of the GNU General Public License as published by
  928. + the Free Software Foundation; either version 2, or (at your option)
  929. + any later version.
  930. +
  931. + This program is distributed in the hope that it will be useful,
  932. + but WITHOUT ANY WARRANTY; without even the implied warranty of
  933. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  934. + GNU General Public License for more details.
  935. +
  936. + You should have received a copy of the GNU General Public License along
  937. + with this program; if not, write to the Free Software Foundation,
  938. + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
  939. +
  940. +#ifndef _GL_POLL_H
  941. +#define _GL_POLL_H
  942. +
  943. +#include <string.h>
  944. +
  945. +/* fake a poll(2) environment */
  946. +#define POLLIN 0x0001 /* any readable data available */
  947. +#define POLLPRI 0x0002 /* OOB/Urgent readable data */
  948. +#define POLLOUT 0x0004 /* file descriptor is writeable */
  949. +#define POLLERR 0x0008 /* some poll error occurred */
  950. +#define POLLHUP 0x0010 /* file descriptor was "hung up" */
  951. +#define POLLNVAL 0x0020 /* requested events "invalid" */
  952. +#define POLLRDNORM 0x0040
  953. +#define POLLRDBAND 0x0080
  954. +#define POLLWRNORM 0x0100
  955. +#define POLLWRBAND 0x0200
  956. +
  957. +#define MSG_WAITALL 0
  958. +#define MSG_DONTWAIT 0x40
  959. +#define MSG_NOSIGNAL 0x400
  960. +
  961. +struct pollfd
  962. +{
  963. + int fd; /* which file descriptor to poll */
  964. + short events; /* events we are interested in */
  965. + short revents; /* events found on return */
  966. +};
  967. +
  968. +typedef unsigned long nfds_t;
  969. +typedef int socklen_t;
  970. +
  971. +extern int poll (struct pollfd *pfd, nfds_t nfd, int timeout);
  972. +
  973. +/* Define INFTIM only if doing so conforms to POSIX. */
  974. +#if !defined (_POSIX_C_SOURCE) && !defined (_XOPEN_SOURCE)
  975. +#define INFTIM (-1)
  976. +#endif
  977. +
  978. +#endif /* _GL_POLL_H */
  979. Index: src/debug/gdb_server.cpp
  980. ===================================================================
  981. --- src/debug/gdb_server.cpp (revision 0)
  982. +++ src/debug/gdb_server.cpp (revision 0)
  983. @@ -0,0 +1,1090 @@
  984. +/*
  985. + * Copyright (C) 2002-2011 The DOSBox Team
  986. + * Copyright (C) 2011 Alexandre Becoulet
  987. + *
  988. + * This program is free software; you can redistribute it and/or modify
  989. + * it under the terms of the GNU General Public License as published by
  990. + * the Free Software Foundation; either version 2 of the License, or
  991. + * (at your option) any later version.
  992. + *
  993. + * This program is distributed in the hope that it will be useful,
  994. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  995. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  996. + * GNU General Public License for more details.
  997. + *
  998. + * You should have received a copy of the GNU General Public License
  999. + * along with this program; if not, write to the Free Software
  1000. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  1001. + */
  1002. +
  1003. +#include "dosbox.h"
  1004. +#if defined(C_GDBSERVER)
  1005. +
  1006. +#include <string.h>
  1007. +#include <list>
  1008. +#include <ctype.h>
  1009. +#include <fstream>
  1010. +#include <iomanip>
  1011. +#include <string>
  1012. +#include <sstream>
  1013. +#include <map>
  1014. +#include <algorithm>
  1015. +#include <vector>
  1016. +
  1017. +using namespace std;
  1018. +
  1019. +#ifdef WIN32
  1020. +//#include <Winsock2.h>
  1021. +#include "poll.h"
  1022. +char * strtok_r (char *s, const char *delim, char **save_ptr) {
  1023. + char *token;
  1024. +
  1025. + if (s == NULL)
  1026. + s = *save_ptr;
  1027. +
  1028. + /* Scan leading delimiters. */
  1029. + s += strspn (s, delim);
  1030. + if (*s == '\0')
  1031. + {
  1032. + *save_ptr = s;
  1033. + return NULL;
  1034. + }
  1035. +
  1036. + /* Find the end of the token. */
  1037. + token = s;
  1038. + s = strpbrk (token, delim);
  1039. + if (s == NULL)
  1040. + /* This token finishes the string. */
  1041. + *save_ptr = token + strlen (token);
  1042. + else
  1043. + {
  1044. + /* Terminate the token and make *SAVE_PTR point past it. */
  1045. + *s = '\0';
  1046. + *save_ptr = s + 1;
  1047. + }
  1048. + return token;
  1049. +}
  1050. +
  1051. +#else
  1052. +#include <netdb.h>
  1053. +#include <sys/socket.h>
  1054. +#include <netinet/in.h>
  1055. +#include <poll.h>
  1056. +#endif
  1057. +#include <assert.h>
  1058. +#include <stdarg.h>
  1059. +
  1060. +#include "debug.h"
  1061. +#include "cpu.h"
  1062. +#include "video.h"
  1063. +#include "pic.h"
  1064. +#include "cpu.h"
  1065. +#include "callback.h"
  1066. +#include "paging.h"
  1067. +#include "setup.h"
  1068. +
  1069. +#define GDB_TCP_PORT 1234
  1070. +
  1071. +// remote protocol debug display, must not call DEBUG_ShowMsg in the end
  1072. +#define GDB_REMOTE_LOG(...) fprintf(stderr, __VA_ARGS__)
  1073. +
  1074. +enum GdbState {
  1075. + GdbNotConnected,
  1076. + GdbRunning,
  1077. + GdbStoped,
  1078. + GdbStep, // set during step by step
  1079. + GdbMonitor, // set during monitor command processing
  1080. +};
  1081. +
  1082. +static GdbState gdb_state = GdbNotConnected;
  1083. +static bool gdb_remote_debug = false;
  1084. +static int gdb_socket, gdb_asocket;
  1085. +
  1086. +static Bit32u step_eip;
  1087. +static Bit16u step_cs;
  1088. +GdbState step_next_state;
  1089. +
  1090. +// breakpoints/watchpoints maps
  1091. +typedef map<Bit32u /* start addr */, size_t /* len */> bp_map_t;
  1092. +static bp_map_t break_points;
  1093. +static bp_map_t read_watch_points;
  1094. +static bp_map_t write_watch_points;
  1095. +
  1096. +// interrupts breakpoints bitmap
  1097. +vector<bool> int_bp(256);
  1098. +
  1099. +Bitu DEBUG_debugCallback;
  1100. +Bitu DEBUG_cycle_count;
  1101. +static Bitu cycle_bp;
  1102. +
  1103. +extern bool DEBUG_logHeavy;
  1104. +
  1105. +static inline Bit32u
  1106. +swapByte32(Bit32u x)
  1107. +{
  1108. + return (((x >> 24) & 0x000000ff) |
  1109. + ((x >> 8 ) & 0x0000ff00) |
  1110. + ((x << 8 ) & 0x00ff0000) |
  1111. + ((x << 24) & 0xff000000));
  1112. +}
  1113. +
  1114. +static inline Bit16u
  1115. +swapByte16(Bit16u x)
  1116. +{
  1117. + return (x >> 8) | (x << 8);
  1118. +}
  1119. +
  1120. +/****************************/
  1121. +/* Gdb cpu registers access */
  1122. +/****************************/
  1123. +
  1124. +enum GdbEipMode {
  1125. + GdbFlatEip,
  1126. + GdbRealEip,
  1127. +};
  1128. +
  1129. +static GdbEipMode gdb_eip_mode = GdbFlatEip;
  1130. +
  1131. +static void gdbSetEip(Bit32u gdb_eip)
  1132. +{
  1133. + /* make gdb client see flat eip value */
  1134. + switch (gdb_eip_mode) {
  1135. + case GdbFlatEip:
  1136. + reg_eip = gdb_eip - SegPhys(cs);
  1137. + break;
  1138. + case GdbRealEip:
  1139. + reg_eip = gdb_eip;
  1140. + break;
  1141. + }
  1142. +}
  1143. +
  1144. +static Bit32u gdbGetEip(void)
  1145. +{
  1146. + switch (gdb_eip_mode) {
  1147. + case GdbFlatEip:
  1148. + return reg_eip + SegPhys(cs);
  1149. + case GdbRealEip:
  1150. + return reg_eip;
  1151. + }
  1152. +}
  1153. +
  1154. +#define GDB_REGS_COUNT 16
  1155. +
  1156. +Bit32u DEBUG_GdbGetRegister(int reg)
  1157. +{
  1158. + switch (reg) {
  1159. + case 0:
  1160. + return swapByte32(reg_eax);
  1161. + case 1:
  1162. + return swapByte32(reg_ecx);
  1163. + case 2:
  1164. + return swapByte32(reg_edx);
  1165. + case 3:
  1166. + return swapByte32(reg_ebx);
  1167. + case 4:
  1168. + return swapByte32(reg_esp);
  1169. + case 5:
  1170. + return swapByte32(reg_ebp);
  1171. + case 6:
  1172. + return swapByte32(reg_esi);
  1173. + case 7:
  1174. + return swapByte32(reg_edi);
  1175. + case 8:
  1176. + return swapByte32(gdbGetEip());
  1177. + case 9:
  1178. + return swapByte32(reg_flags);
  1179. + case 10:
  1180. + return swapByte32(SegValue(cs));
  1181. + case 11:
  1182. + return swapByte32(SegValue(ss));
  1183. + case 12:
  1184. + return swapByte32(SegValue(ds));
  1185. + case 13:
  1186. + return swapByte32(SegValue(es));
  1187. + case 14:
  1188. + return swapByte32(SegValue(fs));
  1189. + case 15:
  1190. + return swapByte32(SegValue(gs));
  1191. + default:
  1192. + return 0;
  1193. + }
  1194. +}
  1195. +
  1196. +int DEBUG_GdbGetRegisterSize(int reg)
  1197. +{
  1198. + switch (reg) {
  1199. + case 0: /* gp regs */
  1200. + case 1:
  1201. + case 2:
  1202. + case 3:
  1203. + case 4:
  1204. + case 5:
  1205. + case 6:
  1206. + case 7:
  1207. + case 8:
  1208. + case 9:
  1209. + return 32;
  1210. +
  1211. + case 10: /* segments */
  1212. + case 11:
  1213. + case 12:
  1214. + case 13:
  1215. + case 14:
  1216. + case 15:
  1217. + return 32;
  1218. +
  1219. + default:
  1220. + return 0;
  1221. + }
  1222. +
  1223. +}
  1224. +
  1225. +void DEBUG_GdbSetRegister(int reg, Bit32u value)
  1226. +{
  1227. + switch (reg) {
  1228. + case 0:
  1229. + reg_eax = swapByte32(value);
  1230. + break;
  1231. + case 1:
  1232. + reg_ecx = swapByte32(value);
  1233. + break;
  1234. + case 2:
  1235. + reg_edx = swapByte32(value);
  1236. + break;
  1237. + case 3:
  1238. + reg_ebx = swapByte32(value);
  1239. + break;
  1240. + case 4:
  1241. + reg_esp = swapByte32(value);
  1242. + break;
  1243. + case 5:
  1244. + reg_ebp = swapByte32(value);
  1245. + break;
  1246. + case 6:
  1247. + reg_esi = swapByte32(value);
  1248. + break;
  1249. + case 7:
  1250. + reg_edi = swapByte32(value);
  1251. + break;
  1252. + case 8:
  1253. + gdbSetEip(swapByte32(value));
  1254. + break;
  1255. + case 9:
  1256. + reg_flags = swapByte32(value);
  1257. + break;
  1258. + case 10:
  1259. + SegSet16(cs, swapByte32(value));
  1260. + break;
  1261. + case 11:
  1262. + SegSet16(ss, swapByte32(value));
  1263. + break;
  1264. + case 12:
  1265. + SegSet16(ds, swapByte32(value));
  1266. + break;
  1267. + case 13:
  1268. + SegSet16(es, swapByte32(value));
  1269. + break;
  1270. + case 14:
  1271. + SegSet16(fs, swapByte32(value));
  1272. + break;
  1273. + case 15:
  1274. + SegSet16(gs, swapByte32(value));
  1275. + break;
  1276. + }
  1277. +}
  1278. +
  1279. +/***********************/
  1280. +/* Gdb remote protocol */
  1281. +/***********************/
  1282. +
  1283. +int DEBUG_GdbWritePacket(const char *data_)
  1284. +{
  1285. + unsigned int i, len = strlen(data_);
  1286. + char ack, end[4];
  1287. + uint8_t chksum = 0;
  1288. + char data[len];
  1289. +
  1290. + memcpy(data, data_, len + 1);
  1291. +
  1292. + unsigned char repeat = 0;
  1293. + unsigned int cmplen = len;
  1294. + char *cmp = data;
  1295. + char *last = 0;
  1296. +
  1297. +#if 1 // gdb RLE data compression
  1298. +
  1299. + for (i = 0; ; ) {
  1300. + if (i < cmplen && last && (*last == cmp[i]) && (repeat + 29 < 126)) {
  1301. + repeat++;
  1302. + } else {
  1303. + if (repeat > 3) {
  1304. + while (repeat == '#' - 29 || repeat == '$' - 29 ||
  1305. + repeat == '+' - 29 || repeat == '-' - 29) {
  1306. + repeat--;
  1307. + last++;
  1308. + }
  1309. + last[1] = '*';
  1310. + last[2] = 29 + repeat;
  1311. + memmove(last + 3, cmp + i, cmplen - i + 1);
  1312. + cmp = last + 3;
  1313. + cmplen -= i;
  1314. + i = 0;
  1315. + last = 0;
  1316. + repeat = 0;
  1317. + continue;
  1318. + } else {
  1319. + last = cmp + i;
  1320. + repeat = 0;
  1321. + }
  1322. +
  1323. + if (i == cmplen)
  1324. + break;
  1325. + }
  1326. + i++;
  1327. + }
  1328. +
  1329. + cmp[cmplen] = 0;
  1330. + len = cmp - data + cmplen;
  1331. +
  1332. +#endif
  1333. +
  1334. + for (i = 0; i < len; i++)
  1335. + chksum += data[i];
  1336. +
  1337. + sprintf(end, "#%02x", chksum);
  1338. +
  1339. + do {
  1340. + if (gdb_remote_debug)
  1341. + GDB_REMOTE_LOG("GDB: sending packet data '%s'\n", data);
  1342. +
  1343. + send(gdb_asocket, "$", 1, MSG_DONTWAIT | MSG_NOSIGNAL);
  1344. + send(gdb_asocket, data, len, MSG_DONTWAIT | MSG_NOSIGNAL);
  1345. + send(gdb_asocket, end, 3, MSG_DONTWAIT | MSG_NOSIGNAL);
  1346. +
  1347. + if (read(gdb_asocket, &ack, 1) < 1) {
  1348. + close(gdb_asocket);
  1349. + gdb_state = GdbNotConnected;
  1350. + return -1;
  1351. + }
  1352. + } while (ack != '+');
  1353. +
  1354. + return 0;
  1355. +}
  1356. +
  1357. +char * DEBUG_GdbReadPacket(char *buffer, size_t size)
  1358. +{
  1359. + int res = read(gdb_asocket, buffer, size);
  1360. +
  1361. + if (res <= 0) {
  1362. + close(gdb_asocket);
  1363. + gdb_state = GdbNotConnected;
  1364. + return 0;
  1365. + }
  1366. +
  1367. + uint8_t sum = 0, chksum = 0;
  1368. + char *data = 0;
  1369. + char *end = 0;
  1370. + int i;
  1371. +
  1372. + // find data in packet
  1373. + for (i = 0; i < res; i++) {
  1374. + switch (buffer[i]) {
  1375. + case '$':
  1376. + sum = 0;
  1377. + data = buffer + i + 1;
  1378. + break;
  1379. +
  1380. + case '#':
  1381. + chksum = sum;
  1382. + end = buffer + i;
  1383. + *end = 0;
  1384. + goto end;
  1385. +
  1386. + default:
  1387. + sum += buffer[i];
  1388. + }
  1389. + }
  1390. + end:
  1391. +
  1392. + // malformed packet
  1393. + if (!end || data >= end) {
  1394. + if (gdb_remote_debug)
  1395. + GDB_REMOTE_LOG("GDB: malformed packet %i bytes\n", res);
  1396. +
  1397. + return 0;
  1398. + }
  1399. +
  1400. + if (gdb_remote_debug)
  1401. + GDB_REMOTE_LOG("GDB: packet with checksum %02x: %s\n", chksum, data);
  1402. +
  1403. + // verify checksum
  1404. + end[3] = 0;
  1405. + if (chksum != strtoul(end + 1, 0, 16)) {
  1406. + send(gdb_asocket, "-", 1, MSG_DONTWAIT | MSG_NOSIGNAL);
  1407. +
  1408. + if (gdb_remote_debug)
  1409. + GDB_REMOTE_LOG("GDB: bad packet checksum\n");
  1410. +
  1411. + return 0;
  1412. + }
  1413. +
  1414. + send(gdb_asocket, "+", 1, MSG_DONTWAIT | MSG_NOSIGNAL);
  1415. +
  1416. + return data;
  1417. +}
  1418. +
  1419. +static bool DEBUG_GdbPointSet(bp_map_t &b, Bit32u addr, size_t len, bool set_)
  1420. +{
  1421. + if (set_) {
  1422. + pair<bp_map_t::iterator, bool> ret = b.insert(bp_map_t::value_type(addr, len));
  1423. +
  1424. + if (!ret.second) // adjust existing point
  1425. + ret.first->second = max(ret.first->second, len);
  1426. + } else {
  1427. + b.erase(addr);
  1428. + }
  1429. +}
  1430. +
  1431. +void DEBUG_GdbProcessMonitorPacket(char *data)
  1432. +{
  1433. + const char *delim = " \t,";
  1434. + char *tokens[255], *save;
  1435. + unsigned int i = 0;
  1436. +
  1437. + for (char *t = strtok_r(data, delim, &save);
  1438. + t != NULL; t = strtok_r(NULL, delim, &save)) {
  1439. + tokens[i++] = t;
  1440. + if (i == 255)
  1441. + break;
  1442. + }
  1443. +
  1444. + if (i >= 2 && !strcmp(tokens[0], "remote_debug")) {
  1445. + gdb_remote_debug = atoi(tokens[1]);
  1446. + DEBUG_GdbWritePacket("OK");
  1447. + return;
  1448. + }
  1449. +
  1450. + if (i >= 1 && !strcmp(tokens[0], "write_log_instruction")) {
  1451. + DEBUG_HeavyWriteLogInstruction();
  1452. + DEBUG_GdbWritePacket("OK");
  1453. + return;
  1454. + }
  1455. +
  1456. + if (i >= 2 && !strcmp(tokens[0], "log_heavy")) {
  1457. + DEBUG_logHeavy = atoi(tokens[1]);
  1458. + DEBUG_GdbWritePacket("OK");
  1459. + return;
  1460. + }
  1461. +
  1462. + if (i >= 2 && !strcmp(tokens[0], "cycle_abs_bp")) {
  1463. + cycle_bp = atoi(tokens[1]);
  1464. + DEBUG_GdbWritePacket("OK");
  1465. + return;
  1466. + }
  1467. +
  1468. + if (i >= 2 && !strcmp(tokens[0], "cycle_bp")) {
  1469. + cycle_bp = DEBUG_cycle_count + atoi(tokens[1]);
  1470. + DEBUG_ShowMsg("GDB: Cycle break point set at %u.\n", cycle_bp);
  1471. + DEBUG_GdbWritePacket("OK");
  1472. + return;
  1473. + }
  1474. +
  1475. + if (i >= 2 && !strcmp(tokens[0], "flat_eip")) {
  1476. + gdb_eip_mode = atoi(tokens[1]) ? GdbFlatEip : GdbRealEip;
  1477. + DEBUG_GdbWritePacket("OK");
  1478. + return;
  1479. + }
  1480. +
  1481. + if (i >= 3 && !strcmp(tokens[0], "int_bp")) {
  1482. + unsigned int inum = strtoul(tokens[1], 0, 0);
  1483. +
  1484. + if (inum < 256) {
  1485. + int_bp[inum] = atoi(tokens[2]);
  1486. + DEBUG_GdbWritePacket("OK");
  1487. + return;
  1488. + }
  1489. + }
  1490. +
  1491. + if (i >= 1 && !strcmp(tokens[0], "log_gdt")) {
  1492. + DEBUG_LogGDT();
  1493. + DEBUG_GdbWritePacket("OK");
  1494. + return;
  1495. + }
  1496. +
  1497. + if (i >= 1 && !strcmp(tokens[0], "log_ldt")) {
  1498. + DEBUG_LogLDT();
  1499. + DEBUG_GdbWritePacket("OK");
  1500. + return;
  1501. + }
  1502. +
  1503. + if (i >= 1 && !strcmp(tokens[0], "log_idt")) {
  1504. + DEBUG_LogIDT();
  1505. + DEBUG_GdbWritePacket("OK");
  1506. + return;
  1507. + }
  1508. +
  1509. + if (i >= 1 && !strcmp(tokens[0], "log_cpuinfo")) {
  1510. + DEBUG_LogCPUInfo();
  1511. + DEBUG_GdbWritePacket("OK");
  1512. + return;
  1513. + }
  1514. +
  1515. + if (i >= 2 && !strcmp(tokens[0], "log_pages")) {
  1516. + DEBUG_LogPages(tokens[1]);
  1517. + DEBUG_GdbWritePacket("OK");
  1518. + return;
  1519. + }
  1520. +
  1521. + DEBUG_ShowMsg("Supported DOSBox Gdb monitor commands:");
  1522. + DEBUG_ShowMsg(" monitor cycle_bp [value] - set relative cycle breakpoint.");
  1523. + DEBUG_ShowMsg(" monitor cycle_abs_bp [value] - set absolute cycle breakpoint.");
  1524. + DEBUG_ShowMsg(" monitor flat_eip [ 0 | 1 ] - enable/disable use of flat eip register value.");
  1525. + DEBUG_ShowMsg(" monitor int_bp [int_num] [ 0 | 1 ] - set breakpoint on cpu interrupt.");
  1526. + DEBUG_ShowMsg(" monitor log_gdt - Lists descriptors of the GDT.");
  1527. + DEBUG_ShowMsg(" monitor log_ldt - Lists descriptors of the LDT.");
  1528. + DEBUG_ShowMsg(" monitor log_idt - Lists descriptors of the IDT.");
  1529. + DEBUG_ShowMsg(" monitor log_cpuinfo - Display CPU status information.");
  1530. + DEBUG_ShowMsg(" monitor log_pages [page] - Display content of page table.");
  1531. + DEBUG_ShowMsg(" monitor remote_debug [ 0 | 1 ] - enable/disable gdb remote protocol debug.");
  1532. + DEBUG_ShowMsg(" monitor set_log_heavy [ 0 | 1 ] - enable/disable heavy CPU logging.");
  1533. + DEBUG_ShowMsg(" monitor write_log_instruction - write instructions log to disk.");
  1534. +
  1535. + DEBUG_GdbWritePacket("");
  1536. +}
  1537. +
  1538. +void DEBUG_GdbProcessPackets()
  1539. +{
  1540. + char buffer[1024];
  1541. + char *data = DEBUG_GdbReadPacket(buffer, 1024);
  1542. +
  1543. + if (!data)
  1544. + return;
  1545. +
  1546. + switch (data[0]) {
  1547. + case 'k': // Kill
  1548. + DEBUG_GdbWritePacket("OK");
  1549. + exit(0);
  1550. + return;
  1551. +
  1552. + case 'D': // Detach
  1553. + DEBUG_GdbWritePacket("OK");
  1554. + close(gdb_asocket);
  1555. + gdb_state = GdbNotConnected;
  1556. + return;
  1557. +
  1558. + case 'q': // Query
  1559. + switch (data[1]) {
  1560. + case 'R': {
  1561. + unsigned int i;
  1562. + char byte[3] = { 0 };
  1563. +
  1564. + if (strncmp(data + 2, "cmd", 3))
  1565. + break;
  1566. +
  1567. + assert(data[5] == ',');
  1568. +
  1569. + data += 6;
  1570. +
  1571. + for (i = 0; data[i * 2]; i++) {
  1572. + memcpy(byte, data + i * 2, 2);
  1573. + data[i] = strtoul(byte, 0, 16);
  1574. + }
  1575. +
  1576. + data[i] = 0;
  1577. +
  1578. + if (gdb_remote_debug)
  1579. + GDB_REMOTE_LOG("GDB: monitor packet: '%s'\n", data);
  1580. +
  1581. + gdb_state = GdbMonitor;
  1582. + DEBUG_GdbProcessMonitorPacket(data);
  1583. + gdb_state = GdbStoped;
  1584. + return;
  1585. + }
  1586. +
  1587. + }
  1588. + DEBUG_GdbWritePacket("");
  1589. + return;
  1590. +
  1591. + case '?': // Indicate the reason the target halted
  1592. + DEBUG_GdbWritePacket("S05"); // SIGTRAP
  1593. + return;
  1594. +
  1595. + case 'p': { // read single register
  1596. + unsigned int reg = strtoul(data + 1, 0, 16);
  1597. + char fmt[32];
  1598. + size_t s = DEBUG_GdbGetRegisterSize(reg);
  1599. +
  1600. + if (s == 0)
  1601. + break;
  1602. +
  1603. + sprintf(fmt, "%%0%ux", s / 4);
  1604. + sprintf(buffer, fmt, DEBUG_GdbGetRegister(reg));
  1605. + DEBUG_GdbWritePacket(buffer);
  1606. + return;
  1607. + }
  1608. +
  1609. + case 'P': { // write single register
  1610. + char *end;
  1611. + unsigned int reg = strtoul(data + 1, &end, 16);
  1612. + assert(*end == '=');
  1613. + uint32_t value = strtoul(end + 1, 0, 16);
  1614. + size_t s = DEBUG_GdbGetRegisterSize(reg);
  1615. +
  1616. + if (s == 0)
  1617. + break;
  1618. +
  1619. + DEBUG_GdbSetRegister(reg, value);
  1620. + DEBUG_GdbWritePacket("OK");
  1621. + return;
  1622. + }
  1623. +
  1624. + case 'g': { // read multiple registers
  1625. + char *b = buffer;
  1626. +
  1627. + for (unsigned int i = 0; i < 1 /* FIXME */; i++) {
  1628. + char fmt[32];
  1629. + sprintf(fmt, "%%0%ux", DEBUG_GdbGetRegisterSize(i) / 4);
  1630. + b += sprintf(b, fmt, DEBUG_GdbGetRegister(i));
  1631. + }
  1632. + DEBUG_GdbWritePacket(buffer);
  1633. + return;
  1634. + }
  1635. +
  1636. + case 'G': { // write multiple registers
  1637. +
  1638. + data++;
  1639. + for (unsigned int i = 0; i < GDB_REGS_COUNT; i++) {
  1640. + size_t s = DEBUG_GdbGetRegisterSize(i) / 4;
  1641. + char word[s + 1];
  1642. + word[s] = 0;
  1643. + memcpy(word, data, s);
  1644. + if (strlen(word) != s)
  1645. + break;
  1646. + DEBUG_GdbSetRegister(i, strtoul(word, 0, 16));
  1647. + data += s;
  1648. + }
  1649. +
  1650. + DEBUG_GdbWritePacket("OK");
  1651. + return;
  1652. + }
  1653. +
  1654. + case 'm': { // read memory
  1655. + char *end;
  1656. + uint32_t addr = strtoul(data + 1, &end, 16);
  1657. + assert(*end == ',');
  1658. + size_t len = strtoul(end + 1, 0, 16);
  1659. +
  1660. + char packet[len * 2 + 1];
  1661. + char *b = packet;
  1662. + bool err = false;
  1663. +
  1664. + if (len % 4 == 0 && addr % 4 == 0) { // use dword access
  1665. + for (unsigned int i = 0; i < len / 4; i++) {
  1666. + Bit32u value;
  1667. + err |= mem_readd_checked(addr + i * 4, &value);
  1668. + b += sprintf(b, "%08x", swapByte32(value));
  1669. + }
  1670. +
  1671. + } else if (len % 2 == 0 && addr % 2 == 0) { // use word access
  1672. + for (unsigned int i = 0; i < len / 2; i++) {
  1673. + Bit16u value;
  1674. + err |= mem_readw_checked(addr + i * 2, &value);
  1675. + b += sprintf(b, "%04x", swapByte16(value));
  1676. + }
  1677. +
  1678. + } else { // use byte access
  1679. + for (unsigned int i = 0; i < len ; i++) {
  1680. + Bit8u value;
  1681. + err |= mem_readb_checked(addr + i, &value);
  1682. + b += sprintf(b, "%02x", value);
  1683. + }
  1684. + }
  1685. +
  1686. + DEBUG_GdbWritePacket(err ? "E0d" : packet);
  1687. + return;
  1688. + }
  1689. +
  1690. + case 'M': { // write memory
  1691. + char *end;
  1692. + uint32_t addr = strtoul(data + 1, &end, 16);
  1693. + assert(*end == ',');
  1694. + size_t len = strtoul(end + 1, &end, 16);
  1695. + assert(*end == ':');
  1696. +
  1697. + char hex[9] = { 0 };
  1698. + bool err = false;
  1699. +
  1700. + if (len % 4 == 0 && addr % 4 == 0) { // use dword access
  1701. + for (unsigned int i = 0; i < len / 4; i++)
  1702. + {
  1703. + memcpy(hex, end + 1 + i * 8, 8);
  1704. + err |= mem_writed_checked(addr + i, swapByte32(strtoul(hex, 0, 16)));
  1705. + }
  1706. +
  1707. + } else if (len % 2 == 0 && addr % 2 == 0) { // use word access
  1708. + for (unsigned int i = 0; i < len / 2; i++)
  1709. + {
  1710. + memcpy(hex, end + 1 + i * 4, 4);
  1711. + err |= mem_writew_checked(addr + i, swapByte16(strtoul(hex, 0, 16)));
  1712. + }
  1713. +
  1714. + } else { // use byte access
  1715. + for (unsigned int i = 0; i < len; i++)
  1716. + {
  1717. + memcpy(hex, end + 1 + i * 2, 2);
  1718. + err |= mem_writeb_checked(addr + i, strtoul(hex, 0, 16));
  1719. + }
  1720. + }
  1721. +
  1722. + DEBUG_GdbWritePacket(err ? "E0d" : "OK");
  1723. + return;
  1724. + }
  1725. +
  1726. + case 'c': { // continue [optional resume addr in hex]
  1727. + if (data[1]) {
  1728. + gdbSetEip(strtoul(data + 1, 0, 16));
  1729. + step_next_state = GdbRunning;
  1730. + } else {
  1731. + // go through single step to avoid break-point on resume address
  1732. + gdb_state = GdbStep;
  1733. + step_next_state = GdbRunning;
  1734. + step_eip = gdbGetEip();
  1735. + step_cs = SegValue(cs);
  1736. + }
  1737. + return;
  1738. + }
  1739. +
  1740. + case 's': { // continue single step [optional resume addr in hex]
  1741. + uint32_t pc;
  1742. +
  1743. + if (data[1])
  1744. + gdbSetEip(strtoul(data + 1, 0, 16));
  1745. +
  1746. + gdb_state = GdbStep;
  1747. + step_next_state = GdbStoped;
  1748. + step_eip = gdbGetEip();
  1749. + step_cs = SegValue(cs);
  1750. + return;
  1751. + }
  1752. +
  1753. + case 'z': // set and clean break points
  1754. + case 'Z': {
  1755. + char *end;
  1756. + uint32_t addr = strtoul(data + 3, &end, 16);
  1757. + assert(*end == ',');
  1758. + size_t len = strtoul(end + 1, 0, 16);
  1759. +
  1760. + switch (data[1]) {
  1761. + case '0':
  1762. + case '1': // execution break point
  1763. + DEBUG_GdbPointSet(break_points, addr, len, data[0] == 'Z');
  1764. + break;
  1765. +
  1766. + case '2': // write watch point
  1767. + DEBUG_GdbPointSet(write_watch_points, addr, len, data[0] == 'Z');
  1768. + break;
  1769. +
  1770. + case '4': // access watch point
  1771. + DEBUG_GdbPointSet(write_watch_points, addr, len, data[0] == 'Z');
  1772. + case '3': // read watch point
  1773. + DEBUG_GdbPointSet(read_watch_points, addr, len, data[0] == 'Z');
  1774. + break;
  1775. +
  1776. + default:
  1777. + DEBUG_GdbWritePacket("");
  1778. + return;
  1779. + }
  1780. +
  1781. + DEBUG_GdbWritePacket("OK");
  1782. + return;
  1783. + }
  1784. +
  1785. + default:
  1786. + break;
  1787. + }
  1788. +
  1789. + // empty reply if not supported
  1790. + DEBUG_GdbWritePacket("");
  1791. +}
  1792. +
  1793. +static bool DEBUG_GdbCheckEvent(void)
  1794. +{
  1795. + struct pollfd pf;
  1796. + char c;
  1797. +
  1798. + switch (gdb_state) {
  1799. + case GdbNotConnected: // check for incoming connection
  1800. + pf.fd = gdb_socket;
  1801. + pf.events = POLLIN | POLLPRI;
  1802. +
  1803. + if (poll(&pf, 1, 0) > 0) {
  1804. + struct sockaddr_in addr;
  1805. + socklen_t addr_size = sizeof(addr);
  1806. +
  1807. + gdb_asocket = accept(gdb_socket, (struct sockaddr*)&addr, &addr_size);
  1808. +
  1809. + if (gdb_asocket >= 0) {
  1810. + gdb_state = GdbStoped;
  1811. + return true;
  1812. + }
  1813. + }
  1814. + break;
  1815. +
  1816. + case GdbStep:
  1817. + case GdbRunning: // try to read CTRL-C from client
  1818. + pf.fd = gdb_asocket;
  1819. + pf.events = POLLIN | POLLPRI;
  1820. +
  1821. + if (poll(&pf, 1, 0) == 1 && read(gdb_asocket, &c, 1) == 1 && c == 3) {
  1822. + DEBUG_ShowMsg("GDB: %u: break requested.\n", DEBUG_cycle_count);
  1823. +
  1824. + gdb_state = GdbStoped;
  1825. + DEBUG_GdbWritePacket("S02"); // sigint
  1826. + return true;
  1827. + }
  1828. + break;
  1829. + }
  1830. +
  1831. + return false;
  1832. +}
  1833. +
  1834. +/**********************/
  1835. +/* dosbox debug stuff */
  1836. +/**********************/
  1837. +
  1838. +void DEBUG_ShowMsg(char const* format,...)
  1839. +{
  1840. + char buf[256];
  1841. + va_list ap;
  1842. + int i;
  1843. +
  1844. + va_start(ap, format);
  1845. + i = vsnprintf(buf, sizeof(buf) - 1, format, ap);
  1846. + buf[i] = 0;
  1847. + va_end(ap);
  1848. +
  1849. + // trim spaces at end
  1850. + for (; i > 0 && buf[i] <= 32; i--)
  1851. + buf[i] = 0;
  1852. +
  1853. + // display message on stderr
  1854. + fprintf(stderr, "%s\n", buf);
  1855. +
  1856. + // send message to gdb client
  1857. + if (gdb_state == GdbRunning || gdb_state == GdbStep || gdb_state == GdbMonitor) {
  1858. + if (buf[0]) {
  1859. + char _p[sizeof(buf) * 2 + 3], *p = _p;
  1860. + int i;
  1861. +
  1862. + *p++ = 'O';
  1863. + for (i = 0; buf[i]; i++)
  1864. + p += sprintf(p, "%02x", buf[i]);
  1865. + *p++ = '0';
  1866. + *p++ = 'a';
  1867. + *p++ = 0;
  1868. +
  1869. + DEBUG_GdbWritePacket(_p);
  1870. + }
  1871. + }
  1872. +
  1873. +}
  1874. +
  1875. +/* called when irq is raised */
  1876. +void DEBUG_IrqBreakpoint(Bit8u intNum)
  1877. +{
  1878. + if (gdb_state == GdbRunning && int_bp[intNum]) {
  1879. + DEBUG_ShowMsg("GDB: %u: processor hardware interrupt 0x%x.\n", DEBUG_cycle_count, intNum);
  1880. +
  1881. + gdb_state = GdbStoped;
  1882. + DEBUG_GdbWritePacket("S05"); // trap
  1883. + DEBUG_EnableDebugger();
  1884. + }
  1885. +}
  1886. +
  1887. +/* called when "int n" opcode is encountered */
  1888. +bool DEBUG_IntBreakpoint(Bit8u intNum)
  1889. +{
  1890. + if (gdb_state == GdbRunning && int_bp[intNum]) {
  1891. + DEBUG_ShowMsg("GDB: %u: processor software interrupt 0x%x.\n", DEBUG_cycle_count, intNum);
  1892. +
  1893. + gdb_state = GdbStoped;
  1894. + DEBUG_GdbWritePacket("S05"); // trap
  1895. + return true;
  1896. + }
  1897. +
  1898. + return false;
  1899. +}
  1900. +
  1901. +/* called when "int3" opcode is encountered */
  1902. +bool DEBUG_Breakpoint(void)
  1903. +{
  1904. + return DEBUG_IntBreakpoint(3);
  1905. +}
  1906. +
  1907. +static inline bool DEBUG_GdbPointCheck(const bp_map_t &b, Bit32u addr)
  1908. +{
  1909. + bp_map_t::const_iterator i = b.lower_bound(addr);
  1910. +
  1911. + return (i != b.end() && i->first <= addr && i->first + i->second > addr);
  1912. +}
  1913. +
  1914. +/* called for each executed instruction */
  1915. +bool DEBUG_HeavyIsBreakpoint(void)
  1916. +{
  1917. + static Bitu last_event_check = 0;
  1918. +
  1919. + void DEBUG_HeavyLogInstruction(void);
  1920. + if (DEBUG_logHeavy)
  1921. + DEBUG_HeavyLogInstruction();
  1922. +
  1923. + /* handle single step end */
  1924. + if (gdb_state == GdbStep && (step_eip != gdbGetEip() || step_cs != SegValue(cs))) {
  1925. + gdb_state = step_next_state;
  1926. +
  1927. + if (gdb_state == GdbStoped) {
  1928. + DEBUG_GdbWritePacket("S05"); // trap
  1929. + return true;
  1930. + }
  1931. + }
  1932. +
  1933. + /* check execution breakpoints */
  1934. + if (gdb_state == GdbRunning) {
  1935. +
  1936. + if (DEBUG_GdbPointCheck(break_points, gdbGetEip())) {
  1937. + DEBUG_ShowMsg("GDB: %u: hit a breakpoint.\n", DEBUG_cycle_count);
  1938. +
  1939. + gdb_state = GdbStoped;
  1940. + DEBUG_GdbWritePacket("S05"); // trap
  1941. + return true;
  1942. + }
  1943. +
  1944. + if (cycle_bp && cycle_bp <= DEBUG_cycle_count) {
  1945. + DEBUG_ShowMsg("GDB: %u: hit a cycle breakpoint.\n", DEBUG_cycle_count);
  1946. +
  1947. + cycle_bp = 0;
  1948. + gdb_state = GdbStoped;
  1949. + DEBUG_GdbWritePacket("S05"); // trap
  1950. + return true;
  1951. + }
  1952. + }
  1953. +
  1954. + /* sometimes check for incoming gdb client connections or CTRL-C from client */
  1955. + if (last_event_check + 16384 < DEBUG_cycle_count) {
  1956. + last_event_check = DEBUG_cycle_count;
  1957. + if (DEBUG_GdbCheckEvent())
  1958. + return true;
  1959. + }
  1960. +
  1961. + return false;
  1962. +}
  1963. +
  1964. +void DEBUG_GdbMemReadHook(Bit32u address, int width)
  1965. +{
  1966. + if ((gdb_state == GdbRunning || gdb_state == GdbStep) && DEBUG_GdbPointCheck(read_watch_points, address)) {
  1967. + DEBUG_ShowMsg("GDB: %u hit a memory read access watchpoint: address=0x%08x.\n", DEBUG_cycle_count, address);
  1968. +
  1969. + gdb_state = GdbStoped;
  1970. + DEBUG_EnableDebugger();
  1971. + DEBUG_GdbWritePacket("S05"); // trap
  1972. + }
  1973. +}
  1974. +
  1975. +void DEBUG_GdbMemWriteHook(Bit32u address, int width, Bit32u value)
  1976. +{
  1977. + if ((gdb_state == GdbRunning || gdb_state == GdbStep) && DEBUG_GdbPointCheck(write_watch_points, address)) {
  1978. + DEBUG_ShowMsg("GDB: %u: hit a memory write access watchpoint: address=0x%08x, new_value=0x%x.\n", DEBUG_cycle_count, address, value);
  1979. +
  1980. + gdb_state = GdbStoped;
  1981. + DEBUG_EnableDebugger();
  1982. + DEBUG_GdbWritePacket("S05"); // trap
  1983. + }
  1984. +}
  1985. +
  1986. +Bitu DEBUG_Loop(void)
  1987. +{
  1988. + GFX_Events();
  1989. + PIC_runIRQs();
  1990. +
  1991. + if (gdb_state == GdbStoped)
  1992. + DEBUG_GdbProcessPackets();
  1993. +
  1994. + if (gdb_state != GdbStoped) {
  1995. + DEBUG_exitLoop = false;
  1996. + DOSBOX_SetNormalLoop();
  1997. + }
  1998. +
  1999. + return 0;
  2000. +}
  2001. +
  2002. +bool DEBUG_ExitLoop(void)
  2003. +{
  2004. + if (DEBUG_exitLoop) {
  2005. + DEBUG_exitLoop = false;
  2006. + return true;
  2007. + }
  2008. + return false;
  2009. +}
  2010. +
  2011. +Bitu DEBUG_EnableDebugger(void)
  2012. +{
  2013. + DEBUG_exitLoop = true;
  2014. + DOSBOX_SetLoop(&DEBUG_Loop);
  2015. + return 0;
  2016. +}
  2017. +
  2018. +void DEBUG_ShutDown(Section *sec)
  2019. +{
  2020. + close(gdb_asocket);
  2021. + close(gdb_socket);
  2022. +}
  2023. +
  2024. +void DEBUG_Init(Section* sec)
  2025. +{
  2026. + /* Setup callback */
  2027. + DEBUG_debugCallback=CALLBACK_Allocate();
  2028. + CALLBACK_Setup(DEBUG_debugCallback,DEBUG_EnableDebugger,CB_RETF,"debugger");
  2029. +
  2030. + /* shutdown function */
  2031. + sec->AddDestroyFunction(&DEBUG_ShutDown);
  2032. +
  2033. + gdb_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  2034. +
  2035. + if (gdb_socket < 0) {
  2036. + LOG_MSG("GDB: Unable to create socket");
  2037. + return;
  2038. + }
  2039. +
  2040. + int tmp = 1;
  2041. +#ifdef WIN32
  2042. + setsockopt(gdb_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)tmp, sizeof(tmp));
  2043. +#else
  2044. + setsockopt(gdb_socket, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
  2045. +#endif
  2046. +
  2047. + struct sockaddr_in addr;
  2048. +
  2049. + int i;
  2050. + for (int i = 0; ; i++) {
  2051. + if (i == 10) {
  2052. + LOG_MSG("GDB: Unable to bind socket");
  2053. + return;
  2054. + }
  2055. +
  2056. + memset(&addr, 0, sizeof(addr));
  2057. + addr.sin_port = htons(GDB_TCP_PORT + i);
  2058. + addr.sin_family = AF_INET;
  2059. +
  2060. + if (bind(gdb_socket, (struct sockaddr*)&addr, sizeof (struct sockaddr_in)) >= 0)
  2061. + break;
  2062. + }
  2063. +
  2064. + if (listen(gdb_socket, 1) < 0) {
  2065. + LOG_MSG("GDB: Unable to listen");
  2066. + return;
  2067. + }
  2068. +
  2069. + LOG_MSG("GDB: listening on TCP port %i", GDB_TCP_PORT + i);
  2070. +}
  2071. +
  2072. +#endif
  2073. +
  2074. Index: src/debug/debug.cpp
  2075. ===================================================================
  2076. --- src/debug/debug.cpp (revision 3761)
  2077. +++ src/debug/debug.cpp (working copy)
  2078. @@ -63,18 +63,9 @@
  2079. static void DEBUG_RaiseTimerIrq(void);
  2080. static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num);
  2081. static void SaveMemoryBin(Bitu seg, Bitu ofs1, Bit32u num);
  2082. -static void LogMCBS(void);
  2083. -static void LogGDT(void);
  2084. -static void LogLDT(void);
  2085. -static void LogIDT(void);
  2086. -static void LogPages(char* selname);
  2087. -static void LogCPUInfo(void);
  2088. static void OutputVecTable(char* filename);
  2089. static void DrawVariables(void);
  2090.  
  2091. -char* AnalyzeInstruction(char* inst, bool saveSelector);
  2092. -Bit32u GetHexValue(char* str, char*& hex);
  2093. -
  2094. #if 0
  2095. class DebugPageHandler : public PageHandler {
  2096. public:
  2097. @@ -97,31 +88,16 @@
  2098. class DEBUG;
  2099.  
  2100. DEBUG* pDebugcom = 0;
  2101. -bool exitLoop = false;
  2102.  
  2103. -
  2104. -// Heavy Debugging Vars for logging
  2105. -#if C_HEAVY_DEBUG
  2106. -static ofstream cpuLogFile;
  2107. -static bool cpuLog = false;
  2108. -static int cpuLogCounter = 0;
  2109. -static int cpuLogType = 1; // log detail
  2110. -static bool zeroProtect = false;
  2111. -bool logHeavy = false;
  2112. -#endif
  2113. -
  2114. -
  2115. -
  2116. static struct {
  2117. Bit32u eax,ebx,ecx,edx,esi,edi,ebp,esp,eip;
  2118. } oldregs;
  2119.  
  2120. -static char curSelectorName[3] = { 0,0,0 };
  2121.  
  2122. static Segment oldsegs[6];
  2123. static Bitu oldflags,oldcpucpl;
  2124. DBGBlock dbg;
  2125. -Bitu cycle_count;
  2126. +Bitu DEBUG_cycle_count;
  2127. static bool debugging;
  2128.  
  2129.  
  2130. @@ -148,10 +124,6 @@
  2131. int inputPos;
  2132. } codeViewData;
  2133.  
  2134. -static Bit16u dataSeg;
  2135. -static Bit32u dataOfs;
  2136. -static bool showExtend = true;
  2137. -
  2138. static void ClearInputLine(void) {
  2139. codeViewData.inputStr[0] = 0;
  2140. codeViewData.inputPos = 0;
  2141. @@ -162,110 +134,8 @@
  2142. static list<string> histBuff;
  2143. static list<string>::iterator histBuffPos = histBuff.end();
  2144.  
  2145. -/***********/
  2146. -/* Helpers */
  2147. -/***********/
  2148. -
  2149. -Bit32u PhysMakeProt(Bit16u selector, Bit32u offset)
  2150. -{
  2151. - Descriptor desc;
  2152. - if (cpu.gdt.GetDescriptor(selector,desc)) return desc.GetBase()+offset;
  2153. - return 0;
  2154. -};
  2155. -
  2156. -Bit32u GetAddress(Bit16u seg, Bit32u offset)
  2157. -{
  2158. - if (seg==SegValue(cs)) return SegPhys(cs)+offset;
  2159. - if (cpu.pmode && !(reg_flags & FLAG_VM)) {
  2160. - Descriptor desc;
  2161. - if (cpu.gdt.GetDescriptor(seg,desc)) return PhysMakeProt(seg,offset);
  2162. - }
  2163. - return (seg<<4)+offset;
  2164. -}
  2165. -
  2166. -static char empty_sel[] = { ' ',' ',0 };
  2167. -
  2168. -bool GetDescriptorInfo(char* selname, char* out1, char* out2)
  2169. -{
  2170. - Bitu sel;
  2171. - Descriptor desc;
  2172. -
  2173. - if (strstr(selname,"cs") || strstr(selname,"CS")) sel = SegValue(cs);
  2174. - else if (strstr(selname,"ds") || strstr(selname,"DS")) sel = SegValue(ds);
  2175. - else if (strstr(selname,"es") || strstr(selname,"ES")) sel = SegValue(es);
  2176. - else if (strstr(selname,"fs") || strstr(selname,"FS")) sel = SegValue(fs);
  2177. - else if (strstr(selname,"gs") || strstr(selname,"GS")) sel = SegValue(gs);
  2178. - else if (strstr(selname,"ss") || strstr(selname,"SS")) sel = SegValue(ss);
  2179. - else {
  2180. - sel = GetHexValue(selname,selname);
  2181. - if (*selname==0) selname=empty_sel;
  2182. - }
  2183. - if (cpu.gdt.GetDescriptor(sel,desc)) {
  2184. - switch (desc.Type()) {
  2185. - case DESC_TASK_GATE:
  2186. - sprintf(out1,"%s: s:%08X type:%02X p",selname,desc.GetSelector(),desc.saved.gate.type);
  2187. - sprintf(out2," TaskGate dpl : %01X %1X",desc.saved.gate.dpl,desc.saved.gate.p);
  2188. - return true;
  2189. - case DESC_LDT:
  2190. - case DESC_286_TSS_A:
  2191. - case DESC_286_TSS_B:
  2192. - case DESC_386_TSS_A:
  2193. - case DESC_386_TSS_B:
  2194. - sprintf(out1,"%s: b:%08X type:%02X pag",selname,desc.GetBase(),desc.saved.seg.type);
  2195. - sprintf(out2," l:%08X dpl : %01X %1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.g);
  2196. - return true;
  2197. - case DESC_286_CALL_GATE:
  2198. - case DESC_386_CALL_GATE:
  2199. - sprintf(out1,"%s: s:%08X type:%02X p params: %02X",selname,desc.GetSelector(),desc.saved.gate.type,desc.saved.gate.paramcount);
  2200. - sprintf(out2," o:%08X dpl : %01X %1X",desc.GetOffset(),desc.saved.gate.dpl,desc.saved.gate.p);
  2201. - return true;
  2202. - case DESC_286_INT_GATE:
  2203. - case DESC_286_TRAP_GATE:
  2204. - case DESC_386_INT_GATE:
  2205. - case DESC_386_TRAP_GATE:
  2206. - sprintf(out1,"%s: s:%08X type:%02X p",selname,desc.GetSelector(),desc.saved.gate.type);
  2207. - sprintf(out2," o:%08X dpl : %01X %1X",desc.GetOffset(),desc.saved.gate.dpl,desc.saved.gate.p);
  2208. - return true;
  2209. - }
  2210. - sprintf(out1,"%s: b:%08X type:%02X parbg",selname,desc.GetBase(),desc.saved.seg.type);
  2211. - sprintf(out2," l:%08X dpl : %01X %1X%1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.big,desc.saved.seg.g);
  2212. - return true;
  2213. - } else {
  2214. - strcpy(out1," ");
  2215. - strcpy(out2," ");
  2216. - }
  2217. - return false;
  2218. -};
  2219. -
  2220. -/********************/
  2221. -/* DebugVar stuff */
  2222. -/********************/
  2223. -
  2224. -class CDebugVar
  2225. -{
  2226. -public:
  2227. - CDebugVar(char* _name, PhysPt _adr) { adr=_adr; safe_strncpy(name,_name,16); };
  2228. -
  2229. - char* GetName(void) { return name; };
  2230. - PhysPt GetAdr (void) { return adr; };
  2231. -
  2232. -private:
  2233. - PhysPt adr;
  2234. - char name[16];
  2235. -
  2236. -public:
  2237. - static void InsertVariable (char* name, PhysPt adr);
  2238. - static CDebugVar* FindVar (PhysPt adr);
  2239. - static void DeleteAll ();
  2240. - static bool SaveVars (char* name);
  2241. - static bool LoadVars (char* name);
  2242. -
  2243. - static std::list<CDebugVar*> varList;
  2244. -};
  2245. -
  2246. std::list<CDebugVar*> CDebugVar::varList;
  2247.  
  2248. -
  2249. /********************/
  2250. /* Breakpoint stuff */
  2251. /********************/
  2252. @@ -281,7 +151,7 @@
  2253. public:
  2254.  
  2255. CBreakpoint(void);
  2256. - void SetAddress (Bit16u seg, Bit32u off) { location = GetAddress(seg,off); type = BKPNT_PHYSICAL; segment = seg; offset = off; };
  2257. + void SetAddress (Bit16u seg, Bit32u off) { location = DEBUG_GetAddress(seg,off); type = BKPNT_PHYSICAL; segment = seg; offset = off; };
  2258. void SetAddress (PhysPt adr) { location = adr; type = BKPNT_PHYSICAL; };
  2259. void SetInt (Bit8u _intNr, Bit16u ah) { intNr = _intNr, ahValue = ah; type = BKPNT_INTERRUPT; };
  2260. void SetOnce (bool _once) { once = _once; };
  2261. @@ -414,7 +284,7 @@
  2262. bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off)
  2263. // Checks if breakpoint is valid an should stop execution
  2264. {
  2265. - if ((ignoreAddressOnce!=0) && (GetAddress(seg,off)==ignoreAddressOnce)) {
  2266. + if ((ignoreAddressOnce!=0) && (DEBUG_GetAddress(seg,off)==ignoreAddressOnce)) {
  2267. ignoreAddressOnce = 0;
  2268. return false;
  2269. } else
  2270. @@ -459,7 +329,7 @@
  2271.  
  2272. Bitu address;
  2273. if (bp->GetType()==BKPNT_MEMORY_LINEAR) address = bp->GetOffset();
  2274. - else address = GetAddress(bp->GetSegment(),bp->GetOffset());
  2275. + else address = DEBUG_GetAddress(bp->GetSegment(),bp->GetOffset());
  2276. Bit8u value=0;
  2277. if (mem_readb_checked(address,&value)) return false;
  2278. if (bp->GetValue() != value) {
  2279. @@ -624,7 +494,7 @@
  2280. /* First get the phyiscal address and check for a set Breakpoint */
  2281. if (!CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) return false;
  2282. // Found. Breakpoint is valid
  2283. - PhysPt where=GetAddress(SegValue(cs),reg_eip);
  2284. + PhysPt where=DEBUG_GetAddress(SegValue(cs),reg_eip);
  2285. CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints
  2286. return true;
  2287. };
  2288. @@ -632,7 +502,7 @@
  2289. bool DEBUG_IntBreakpoint(Bit8u intNum)
  2290. {
  2291. /* First get the phyiscal address and check for a set Breakpoint */
  2292. - PhysPt where=GetAddress(SegValue(cs),reg_eip);
  2293. + PhysPt where=DEBUG_GetAddress(SegValue(cs),reg_eip);
  2294. if (!CBreakpoint::CheckIntBreakpoint(where,intNum,reg_ah)) return false;
  2295. // Found. Breakpoint is valid
  2296. CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints
  2297. @@ -641,8 +511,8 @@
  2298.  
  2299. static bool StepOver()
  2300. {
  2301. - exitLoop = false;
  2302. - PhysPt start=GetAddress(SegValue(cs),reg_eip);
  2303. + DEBUG_exitLoop = false;
  2304. + PhysPt start=DEBUG_GetAddress(SegValue(cs),reg_eip);
  2305. char dline[200];Bitu size;
  2306. size=DasmI386(dline, start, reg_eip, cpu.code.big);
  2307.  
  2308. @@ -663,8 +533,8 @@
  2309. DrawVariables();
  2310. #endif
  2311.  
  2312. - if (exitLoop) {
  2313. - exitLoop = false;
  2314. + if (DEBUG_exitLoop) {
  2315. + DEBUG_exitLoop = false;
  2316. return true;
  2317. }
  2318. return false;
  2319. @@ -677,15 +547,15 @@
  2320. static void DrawData(void) {
  2321.  
  2322. Bit8u ch;
  2323. - Bit32u add = dataOfs;
  2324. + Bit32u add = DEBUG_dataOfs;
  2325. Bit32u address;
  2326. /* Data win */
  2327. for (int y=0; y<8; y++) {
  2328. // Address
  2329. - if (add<0x10000) mvwprintw (dbg.win_data,1+y,0,"%04X:%04X ",dataSeg,add);
  2330. - else mvwprintw (dbg.win_data,1+y,0,"%04X:%08X ",dataSeg,add);
  2331. + if (add<0x10000) mvwprintw (dbg.win_data,1+y,0,"%04X:%04X ",DEBUG_dataSeg,add);
  2332. + else mvwprintw (dbg.win_data,1+y,0,"%04X:%08X ",DEBUG_dataSeg,add);
  2333. for (int x=0; x<16; x++) {
  2334. - address = GetAddress(dataSeg,add);
  2335. + address = DEBUG_GetAddress(DEBUG_dataSeg,add);
  2336. if (mem_readb_checked(address,&ch)) ch=0;
  2337. mvwprintw (dbg.win_data,1+y,14+3*x,"%02X",ch);
  2338. if (ch<32 || !isprint(*reinterpret_cast<unsigned char*>(&ch))) ch='.';
  2339. @@ -757,22 +627,22 @@
  2340. mvwprintw(dbg.win_reg,0,76,"Real");
  2341.  
  2342. // Selector info, if available
  2343. - if ((cpu.pmode) && curSelectorName[0]) {
  2344. + if ((cpu.pmode) && DEBUG_curSelectorName[0]) {
  2345. char out1[200], out2[200];
  2346. - GetDescriptorInfo(curSelectorName,out1,out2);
  2347. + DEBUG_GetDescriptorInfo(DEBUG_curSelectorName,out1,out2);
  2348. mvwprintw(dbg.win_reg,2,28,out1);
  2349. mvwprintw(dbg.win_reg,3,28,out2);
  2350. }
  2351.  
  2352. wattrset(dbg.win_reg,0);
  2353. - mvwprintw(dbg.win_reg,3,60,"%u ",cycle_count);
  2354. + mvwprintw(dbg.win_reg,3,60,"%u ",DEBUG_cycle_count);
  2355. wrefresh(dbg.win_reg);
  2356. };
  2357.  
  2358. static void DrawCode(void) {
  2359. bool saveSel;
  2360. Bit32u disEIP = codeViewData.useEIP;
  2361. - PhysPt start = GetAddress(codeViewData.useCS,codeViewData.useEIP);
  2362. + PhysPt start = DEBUG_GetAddress(codeViewData.useCS,codeViewData.useEIP);
  2363. char dline[200];Bitu size;Bitu c;
  2364. static char line20[21] = " ";
  2365.  
  2366. @@ -822,7 +692,7 @@
  2367.  
  2368. char empty_res[] = { 0 };
  2369. char* res = empty_res;
  2370. - if (showExtend) res = AnalyzeInstruction(dline, saveSel);
  2371. + if (DEBUG_showExtend) res = DEBUG_AnalyzeInstruction(dline, saveSel);
  2372. // Spacepad it up to 28 characters
  2373. size_t dline_len = strlen(dline);
  2374. if(dline_len < 28) for (c = dline_len; c < 28;c++) dline[c] = ' '; dline[28] = 0;
  2375. @@ -882,86 +752,42 @@
  2376. /* User input */
  2377. /********************/
  2378.  
  2379. -Bit32u GetHexValue(char* str, char*& hex)
  2380. -{
  2381. - Bit32u value = 0;
  2382. - Bit32u regval = 0;
  2383. - hex = str;
  2384. - while (*hex==' ') hex++;
  2385. - if (strstr(hex,"EAX")==hex) { hex+=3; regval = reg_eax; };
  2386. - if (strstr(hex,"EBX")==hex) { hex+=3; regval = reg_ebx; };
  2387. - if (strstr(hex,"ECX")==hex) { hex+=3; regval = reg_ecx; };
  2388. - if (strstr(hex,"EDX")==hex) { hex+=3; regval = reg_edx; };
  2389. - if (strstr(hex,"ESI")==hex) { hex+=3; regval = reg_esi; };
  2390. - if (strstr(hex,"EDI")==hex) { hex+=3; regval = reg_edi; };
  2391. - if (strstr(hex,"EBP")==hex) { hex+=3; regval = reg_ebp; };
  2392. - if (strstr(hex,"ESP")==hex) { hex+=3; regval = reg_esp; };
  2393. - if (strstr(hex,"EIP")==hex) { hex+=3; regval = reg_eip; };
  2394. - if (strstr(hex,"AX")==hex) { hex+=2; regval = reg_ax; };
  2395. - if (strstr(hex,"BX")==hex) { hex+=2; regval = reg_bx; };
  2396. - if (strstr(hex,"CX")==hex) { hex+=2; regval = reg_cx; };
  2397. - if (strstr(hex,"DX")==hex) { hex+=2; regval = reg_dx; };
  2398. - if (strstr(hex,"SI")==hex) { hex+=2; regval = reg_si; };
  2399. - if (strstr(hex,"DI")==hex) { hex+=2; regval = reg_di; };
  2400. - if (strstr(hex,"BP")==hex) { hex+=2; regval = reg_bp; };
  2401. - if (strstr(hex,"SP")==hex) { hex+=2; regval = reg_sp; };
  2402. - if (strstr(hex,"IP")==hex) { hex+=2; regval = reg_ip; };
  2403. - if (strstr(hex,"CS")==hex) { hex+=2; regval = SegValue(cs); };
  2404. - if (strstr(hex,"DS")==hex) { hex+=2; regval = SegValue(ds); };
  2405. - if (strstr(hex,"ES")==hex) { hex+=2; regval = SegValue(es); };
  2406. - if (strstr(hex,"FS")==hex) { hex+=2; regval = SegValue(fs); };
  2407. - if (strstr(hex,"GS")==hex) { hex+=2; regval = SegValue(gs); };
  2408. - if (strstr(hex,"SS")==hex) { hex+=2; regval = SegValue(ss); };
  2409. -
  2410. - while (*hex) {
  2411. - if ((*hex>='0') && (*hex<='9')) value = (value<<4)+*hex-'0';
  2412. - else if ((*hex>='A') && (*hex<='F')) value = (value<<4)+*hex-'A'+10;
  2413. - else {
  2414. - if(*hex == '+') {hex++;return regval + value + GetHexValue(hex,hex); };
  2415. - if(*hex == '-') {hex++;return regval + value - GetHexValue(hex,hex); };
  2416. - break; // No valid char
  2417. - }
  2418. - hex++;
  2419. - };
  2420. - return regval + value;
  2421. -};
  2422. -
  2423. bool ChangeRegister(char* str)
  2424. {
  2425. char* hex = str;
  2426. while (*hex==' ') hex++;
  2427. - if (strstr(hex,"EAX")==hex) { hex+=3; reg_eax = GetHexValue(hex,hex); } else
  2428. - if (strstr(hex,"EBX")==hex) { hex+=3; reg_ebx = GetHexValue(hex,hex); } else
  2429. - if (strstr(hex,"ECX")==hex) { hex+=3; reg_ecx = GetHexValue(hex,hex); } else
  2430. - if (strstr(hex,"EDX")==hex) { hex+=3; reg_edx = GetHexValue(hex,hex); } else
  2431. - if (strstr(hex,"ESI")==hex) { hex+=3; reg_esi = GetHexValue(hex,hex); } else
  2432. - if (strstr(hex,"EDI")==hex) { hex+=3; reg_edi = GetHexValue(hex,hex); } else
  2433. - if (strstr(hex,"EBP")==hex) { hex+=3; reg_ebp = GetHexValue(hex,hex); } else
  2434. - if (strstr(hex,"ESP")==hex) { hex+=3; reg_esp = GetHexValue(hex,hex); } else
  2435. - if (strstr(hex,"EIP")==hex) { hex+=3; reg_eip = GetHexValue(hex,hex); } else
  2436. - if (strstr(hex,"AX")==hex) { hex+=2; reg_ax = (Bit16u)GetHexValue(hex,hex); } else
  2437. - if (strstr(hex,"BX")==hex) { hex+=2; reg_bx = (Bit16u)GetHexValue(hex,hex); } else
  2438. - if (strstr(hex,"CX")==hex) { hex+=2; reg_cx = (Bit16u)GetHexValue(hex,hex); } else
  2439. - if (strstr(hex,"DX")==hex) { hex+=2; reg_dx = (Bit16u)GetHexValue(hex,hex); } else
  2440. - if (strstr(hex,"SI")==hex) { hex+=2; reg_si = (Bit16u)GetHexValue(hex,hex); } else
  2441. - if (strstr(hex,"DI")==hex) { hex+=2; reg_di = (Bit16u)GetHexValue(hex,hex); } else
  2442. - if (strstr(hex,"BP")==hex) { hex+=2; reg_bp = (Bit16u)GetHexValue(hex,hex); } else
  2443. - if (strstr(hex,"SP")==hex) { hex+=2; reg_sp = (Bit16u)GetHexValue(hex,hex); } else
  2444. - if (strstr(hex,"IP")==hex) { hex+=2; reg_ip = (Bit16u)GetHexValue(hex,hex); } else
  2445. - if (strstr(hex,"CS")==hex) { hex+=2; SegSet16(cs,(Bit16u)GetHexValue(hex,hex)); } else
  2446. - if (strstr(hex,"DS")==hex) { hex+=2; SegSet16(ds,(Bit16u)GetHexValue(hex,hex)); } else
  2447. - if (strstr(hex,"ES")==hex) { hex+=2; SegSet16(es,(Bit16u)GetHexValue(hex,hex)); } else
  2448. - if (strstr(hex,"FS")==hex) { hex+=2; SegSet16(fs,(Bit16u)GetHexValue(hex,hex)); } else
  2449. - if (strstr(hex,"GS")==hex) { hex+=2; SegSet16(gs,(Bit16u)GetHexValue(hex,hex)); } else
  2450. - if (strstr(hex,"SS")==hex) { hex+=2; SegSet16(ss,(Bit16u)GetHexValue(hex,hex)); } else
  2451. - if (strstr(hex,"AF")==hex) { hex+=2; SETFLAGBIT(AF,GetHexValue(hex,hex)); } else
  2452. - if (strstr(hex,"CF")==hex) { hex+=2; SETFLAGBIT(CF,GetHexValue(hex,hex)); } else
  2453. - if (strstr(hex,"DF")==hex) { hex+=2; SETFLAGBIT(DF,GetHexValue(hex,hex)); } else
  2454. - if (strstr(hex,"IF")==hex) { hex+=2; SETFLAGBIT(IF,GetHexValue(hex,hex)); } else
  2455. - if (strstr(hex,"OF")==hex) { hex+=2; SETFLAGBIT(OF,GetHexValue(hex,hex)); } else
  2456. - if (strstr(hex,"ZF")==hex) { hex+=2; SETFLAGBIT(ZF,GetHexValue(hex,hex)); } else
  2457. - if (strstr(hex,"PF")==hex) { hex+=2; SETFLAGBIT(PF,GetHexValue(hex,hex)); } else
  2458. - if (strstr(hex,"SF")==hex) { hex+=2; SETFLAGBIT(SF,GetHexValue(hex,hex)); } else
  2459. + if (strstr(hex,"EAX")==hex) { hex+=3; reg_eax = DEBUG_GetHexValue(hex,hex); } else
  2460. + if (strstr(hex,"EBX")==hex) { hex+=3; reg_ebx = DEBUG_GetHexValue(hex,hex); } else
  2461. + if (strstr(hex,"ECX")==hex) { hex+=3; reg_ecx = DEBUG_GetHexValue(hex,hex); } else
  2462. + if (strstr(hex,"EDX")==hex) { hex+=3; reg_edx = DEBUG_GetHexValue(hex,hex); } else
  2463. + if (strstr(hex,"ESI")==hex) { hex+=3; reg_esi = DEBUG_GetHexValue(hex,hex); } else
  2464. + if (strstr(hex,"EDI")==hex) { hex+=3; reg_edi = DEBUG_GetHexValue(hex,hex); } else
  2465. + if (strstr(hex,"EBP")==hex) { hex+=3; reg_ebp = DEBUG_GetHexValue(hex,hex); } else
  2466. + if (strstr(hex,"ESP")==hex) { hex+=3; reg_esp = DEBUG_GetHexValue(hex,hex); } else
  2467. + if (strstr(hex,"EIP")==hex) { hex+=3; reg_eip = DEBUG_GetHexValue(hex,hex); } else
  2468. + if (strstr(hex,"AX")==hex) { hex+=2; reg_ax = (Bit16u)DEBUG_GetHexValue(hex,hex); } else
  2469. + if (strstr(hex,"BX")==hex) { hex+=2; reg_bx = (Bit16u)DEBUG_GetHexValue(hex,hex); } else
  2470. + if (strstr(hex,"CX")==hex) { hex+=2; reg_cx = (Bit16u)DEBUG_GetHexValue(hex,hex); } else
  2471. + if (strstr(hex,"DX")==hex) { hex+=2; reg_dx = (Bit16u)DEBUG_GetHexValue(hex,hex); } else
  2472. + if (strstr(hex,"SI")==hex) { hex+=2; reg_si = (Bit16u)DEBUG_GetHexValue(hex,hex); } else
  2473. + if (strstr(hex,"DI")==hex) { hex+=2; reg_di = (Bit16u)DEBUG_GetHexValue(hex,hex); } else
  2474. + if (strstr(hex,"BP")==hex) { hex+=2; reg_bp = (Bit16u)DEBUG_GetHexValue(hex,hex); } else
  2475. + if (strstr(hex,"SP")==hex) { hex+=2; reg_sp = (Bit16u)DEBUG_GetHexValue(hex,hex); } else
  2476. + if (strstr(hex,"IP")==hex) { hex+=2; reg_ip = (Bit16u)DEBUG_GetHexValue(hex,hex); } else
  2477. + if (strstr(hex,"CS")==hex) { hex+=2; SegSet16(cs,(Bit16u)DEBUG_GetHexValue(hex,hex)); } else
  2478. + if (strstr(hex,"DS")==hex) { hex+=2; SegSet16(ds,(Bit16u)DEBUG_GetHexValue(hex,hex)); } else
  2479. + if (strstr(hex,"ES")==hex) { hex+=2; SegSet16(es,(Bit16u)DEBUG_GetHexValue(hex,hex)); } else
  2480. + if (strstr(hex,"FS")==hex) { hex+=2; SegSet16(fs,(Bit16u)DEBUG_GetHexValue(hex,hex)); } else
  2481. + if (strstr(hex,"GS")==hex) { hex+=2; SegSet16(gs,(Bit16u)DEBUG_GetHexValue(hex,hex)); } else
  2482. + if (strstr(hex,"SS")==hex) { hex+=2; SegSet16(ss,(Bit16u)DEBUG_GetHexValue(hex,hex)); } else
  2483. + if (strstr(hex,"AF")==hex) { hex+=2; SETFLAGBIT(AF,DEBUG_GetHexValue(hex,hex)); } else
  2484. + if (strstr(hex,"CF")==hex) { hex+=2; SETFLAGBIT(CF,DEBUG_GetHexValue(hex,hex)); } else
  2485. + if (strstr(hex,"DF")==hex) { hex+=2; SETFLAGBIT(DF,DEBUG_GetHexValue(hex,hex)); } else
  2486. + if (strstr(hex,"IF")==hex) { hex+=2; SETFLAGBIT(IF,DEBUG_GetHexValue(hex,hex)); } else
  2487. + if (strstr(hex,"OF")==hex) { hex+=2; SETFLAGBIT(OF,DEBUG_GetHexValue(hex,hex)); } else
  2488. + if (strstr(hex,"ZF")==hex) { hex+=2; SETFLAGBIT(ZF,DEBUG_GetHexValue(hex,hex)); } else
  2489. + if (strstr(hex,"PF")==hex) { hex+=2; SETFLAGBIT(PF,DEBUG_GetHexValue(hex,hex)); } else
  2490. + if (strstr(hex,"SF")==hex) { hex+=2; SETFLAGBIT(SF,DEBUG_GetHexValue(hex,hex)); } else
  2491. { return false; };
  2492. return true;
  2493. };
  2494. @@ -982,24 +808,24 @@
  2495. found = const_cast<char*>(s_found.c_str());
  2496.  
  2497. if (command == "MEMDUMP") { // Dump memory to file
  2498. - Bit16u seg = (Bit16u)GetHexValue(found,found); found++;
  2499. - Bit32u ofs = GetHexValue(found,found); found++;
  2500. - Bit32u num = GetHexValue(found,found); found++;
  2501. + Bit16u seg = (Bit16u)DEBUG_GetHexValue(found,found); found++;
  2502. + Bit32u ofs = DEBUG_GetHexValue(found,found); found++;
  2503. + Bit32u num = DEBUG_GetHexValue(found,found); found++;
  2504. SaveMemory(seg,ofs,num);
  2505. return true;
  2506. };
  2507.  
  2508. if (command == "MEMDUMPBIN") { // Dump memory to file bineary
  2509. - Bit16u seg = (Bit16u)GetHexValue(found,found); found++;
  2510. - Bit32u ofs = GetHexValue(found,found); found++;
  2511. - Bit32u num = GetHexValue(found,found); found++;
  2512. + Bit16u seg = (Bit16u)DEBUG_GetHexValue(found,found); found++;
  2513. + Bit32u ofs = DEBUG_GetHexValue(found,found); found++;
  2514. + Bit32u num = DEBUG_GetHexValue(found,found); found++;
  2515. SaveMemoryBin(seg,ofs,num);
  2516. return true;
  2517. };
  2518.  
  2519. if (command == "IV") { // Insert variable
  2520. - Bit16u seg = (Bit16u)GetHexValue(found,found); found++;
  2521. - Bit32u ofs = (Bit16u)GetHexValue(found,found); found++;
  2522. + Bit16u seg = (Bit16u)DEBUG_GetHexValue(found,found); found++;
  2523. + Bit32u ofs = (Bit16u)DEBUG_GetHexValue(found,found); found++;
  2524. char name[16];
  2525. for (int i=0; i<16; i++) {
  2526. if (found[i] && (found[i]!=' ')) name[i] = found[i];
  2527. @@ -1009,7 +835,7 @@
  2528.  
  2529. if(!name[0]) return false;
  2530. DEBUG_ShowMsg("DEBUG: Created debug var %s at %04X:%04X\n",name,seg,ofs);
  2531. - CDebugVar::InsertVariable(name,GetAddress(seg,ofs));
  2532. + CDebugVar::InsertVariable(name,DEBUG_GetAddress(seg,ofs));
  2533. return true;
  2534. };
  2535.  
  2536. @@ -1043,15 +869,15 @@
  2537. };
  2538.  
  2539. if (command == "SM") { // Set memory with following values
  2540. - Bit16u seg = (Bit16u)GetHexValue(found,found); found++;
  2541. - Bit32u ofs = GetHexValue(found,found); found++;
  2542. + Bit16u seg = (Bit16u)DEBUG_GetHexValue(found,found); found++;
  2543. + Bit32u ofs = DEBUG_GetHexValue(found,found); found++;
  2544. Bit16u count = 0;
  2545. while (*found) {
  2546. while (*found==' ') found++;
  2547. if (*found) {
  2548. - Bit8u value = (Bit8u)GetHexValue(found,found);
  2549. + Bit8u value = (Bit8u)DEBUG_GetHexValue(found,found);
  2550. if(*found) found++;
  2551. - mem_writeb_checked(GetAddress(seg,ofs+count),value);
  2552. + mem_writeb_checked(DEBUG_GetAddress(seg,ofs+count),value);
  2553. count++;
  2554. }
  2555. };
  2556. @@ -1060,8 +886,8 @@
  2557. };
  2558.  
  2559. if (command == "BP") { // Add new breakpoint
  2560. - Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":"
  2561. - Bit32u ofs = GetHexValue(found,found);
  2562. + Bit16u seg = (Bit16u)DEBUG_GetHexValue(found,found);found++; // skip ":"
  2563. + Bit32u ofs = DEBUG_GetHexValue(found,found);
  2564. CBreakpoint::AddBreakpoint(seg,ofs,false);
  2565. DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X\n",seg,ofs);
  2566. return true;
  2567. @@ -1070,16 +896,16 @@
  2568. #if C_HEAVY_DEBUG
  2569.  
  2570. if (command == "BPM") { // Add new breakpoint
  2571. - Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":"
  2572. - Bit32u ofs = GetHexValue(found,found);
  2573. + Bit16u seg = (Bit16u)DEBUG_GetHexValue(found,found);found++; // skip ":"
  2574. + Bit32u ofs = DEBUG_GetHexValue(found,found);
  2575. CBreakpoint::AddMemBreakpoint(seg,ofs);
  2576. DEBUG_ShowMsg("DEBUG: Set memory breakpoint at %04X:%04X\n",seg,ofs);
  2577. return true;
  2578. };
  2579.  
  2580. if (command == "BPPM") { // Add new breakpoint
  2581. - Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":"
  2582. - Bit32u ofs = GetHexValue(found,found);
  2583. + Bit16u seg = (Bit16u)DEBUG_GetHexValue(found,found);found++; // skip ":"
  2584. + Bit32u ofs = DEBUG_GetHexValue(found,found);
  2585. CBreakpoint* bp = CBreakpoint::AddMemBreakpoint(seg,ofs);
  2586. if (bp) {
  2587. bp->SetType(BKPNT_MEMORY_PROT);
  2588. @@ -1089,7 +915,7 @@
  2589. };
  2590.  
  2591. if (command == "BPLM") { // Add new breakpoint
  2592. - Bit32u ofs = GetHexValue(found,found);
  2593. + Bit32u ofs = DEBUG_GetHexValue(found,found);
  2594. CBreakpoint* bp = CBreakpoint::AddMemBreakpoint(0,ofs);
  2595. if (bp) bp->SetType(BKPNT_MEMORY_LINEAR);
  2596. DEBUG_ShowMsg("DEBUG: Set linear memory breakpoint at %08X\n",ofs);
  2597. @@ -1099,9 +925,9 @@
  2598. #endif
  2599.  
  2600. if (command == "BPINT") { // Add Interrupt Breakpoint
  2601. - Bit8u intNr = (Bit8u)GetHexValue(found,found);
  2602. + Bit8u intNr = (Bit8u)DEBUG_GetHexValue(found,found);
  2603. bool all = !(*found);found++;
  2604. - Bit8u valAH = (Bit8u)GetHexValue(found,found);
  2605. + Bit8u valAH = (Bit8u)DEBUG_GetHexValue(found,found);
  2606. if ((valAH==0x00) && (*found=='*' || all)) {
  2607. CBreakpoint::AddIntBreakpoint(intNr,BPINT_ALL,false);
  2608. DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X\n",intNr);
  2609. @@ -1120,7 +946,7 @@
  2610. };
  2611.  
  2612. if (command == "BPDEL") { // Delete Breakpoints
  2613. - Bit8u bpNr = (Bit8u)GetHexValue(found,found);
  2614. + Bit8u bpNr = (Bit8u)DEBUG_GetHexValue(found,found);
  2615. if ((bpNr==0x00) && (*found=='*')) { // Delete all
  2616. CBreakpoint::DeleteAll();
  2617. DEBUG_ShowMsg("DEBUG: Breakpoints deleted.\n");
  2618. @@ -1132,8 +958,8 @@
  2619. };
  2620.  
  2621. if (command == "C") { // Set code overview
  2622. - Bit16u codeSeg = (Bit16u)GetHexValue(found,found); found++;
  2623. - Bit32u codeOfs = GetHexValue(found,found);
  2624. + Bit16u codeSeg = (Bit16u)DEBUG_GetHexValue(found,found); found++;
  2625. + Bit32u codeOfs = DEBUG_GetHexValue(found,found);
  2626. DEBUG_ShowMsg("DEBUG: Set code overview to %04X:%04X\n",codeSeg,codeOfs);
  2627. codeViewData.useCS = codeSeg;
  2628. codeViewData.useEIP = codeOfs;
  2629. @@ -1142,40 +968,40 @@
  2630. };
  2631.  
  2632. if (command == "D") { // Set data overview
  2633. - dataSeg = (Bit16u)GetHexValue(found,found); found++;
  2634. - dataOfs = GetHexValue(found,found);
  2635. - DEBUG_ShowMsg("DEBUG: Set data overview to %04X:%04X\n",dataSeg,dataOfs);
  2636. + DEBUG_dataSeg = (Bit16u)DEBUG_GetHexValue(found,found); found++;
  2637. + DEBUG_dataOfs = DEBUG_GetHexValue(found,found);
  2638. + DEBUG_ShowMsg("DEBUG: Set data overview to %04X:%04X\n",DEBUG_dataSeg,DEBUG_dataOfs);
  2639. return true;
  2640. };
  2641.  
  2642. #if C_HEAVY_DEBUG
  2643.  
  2644. if (command == "LOG") { // Create Cpu normal log file
  2645. - cpuLogType = 1;
  2646. + DEBUG_cpuLogType = 1;
  2647. command = "logcode";
  2648. }
  2649.  
  2650. if (command == "LOGS") { // Create Cpu short log file
  2651. - cpuLogType = 0;
  2652. + DEBUG_cpuLogType = 0;
  2653. command = "logcode";
  2654. }
  2655.  
  2656. if (command == "LOGL") { // Create Cpu long log file
  2657. - cpuLogType = 2;
  2658. + DEBUG_cpuLogType = 2;
  2659. command = "logcode";
  2660. }
  2661.  
  2662. if (command == "logcode") { //Shared code between all logs
  2663. DEBUG_ShowMsg("DEBUG: Starting log\n");
  2664. - cpuLogFile.open("LOGCPU.TXT");
  2665. - if (!cpuLogFile.is_open()) {
  2666. + DEBUG_cpuLogFile.open("LOGCPU.TXT");
  2667. + if (!DEBUG_cpuLogFile.is_open()) {
  2668. DEBUG_ShowMsg("DEBUG: Logfile couldn't be created.\n");
  2669. return false;
  2670. }
  2671. //Initialize log object
  2672. - cpuLogFile << hex << noshowbase << setfill('0') << uppercase;
  2673. - cpuLog = true;
  2674. - cpuLogCounter = GetHexValue(found,found);
  2675. + DEBUG_cpuLogFile << hex << noshowbase << setfill('0') << uppercase;
  2676. + DEBUG_cpuLog = true;
  2677. + DEBUG_cpuLogCounter = DEBUG_GetHexValue(found,found);
  2678.  
  2679. debugging = false;
  2680. CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true);
  2681. @@ -1187,7 +1013,7 @@
  2682. #endif
  2683.  
  2684. if (command == "INTT") { //trace int.
  2685. - Bit8u intNr = (Bit8u)GetHexValue(found,found);
  2686. + Bit8u intNr = (Bit8u)DEBUG_GetHexValue(found,found);
  2687. DEBUG_ShowMsg("DEBUG: Tracing INT %02X\n",intNr);
  2688. CPU_HW_Interrupt(intNr);
  2689. SetCodeWinStart();
  2690. @@ -1195,7 +1021,7 @@
  2691. };
  2692.  
  2693. if (command == "INT") { // start int.
  2694. - Bit8u intNr = (Bit8u)GetHexValue(found,found);
  2695. + Bit8u intNr = (Bit8u)DEBUG_GetHexValue(found,found);
  2696. DEBUG_ShowMsg("DEBUG: Starting INT %02X\n",intNr);
  2697. CBreakpoint::AddBreakpoint(SegValue(cs),reg_eip, true);
  2698. CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip-1,true);
  2699. @@ -1209,26 +1035,26 @@
  2700. if (command == "SELINFO") {
  2701. while (found[0] == ' ') found++;
  2702. char out1[200],out2[200];
  2703. - GetDescriptorInfo(found,out1,out2);
  2704. + DEBUG_GetDescriptorInfo(found,out1,out2);
  2705. DEBUG_ShowMsg("SelectorInfo %s:\n%s\n%s\n",found,out1,out2);
  2706. return true;
  2707. };
  2708.  
  2709. if (command == "DOS") {
  2710. stream >> command;
  2711. - if (command == "MCBS") LogMCBS();
  2712. + if (command == "MCBS") DEBUG_LogMCBS();
  2713. return true;
  2714. }
  2715.  
  2716. - if (command == "GDT") {LogGDT(); return true;}
  2717. + if (command == "GDT") {DEBUG_LogGDT(); return true;}
  2718.  
  2719. - if (command == "LDT") {LogLDT(); return true;}
  2720. + if (command == "LDT") {DEBUG_LogLDT(); return true;}
  2721.  
  2722. - if (command == "IDT") {LogIDT(); return true;}
  2723. + if (command == "IDT") {DEBUG_LogIDT(); return true;}
  2724.  
  2725. - if (command == "PAGING") {LogPages(found); return true;}
  2726. + if (command == "PAGING") {DEBUG_LogPages(found); return true;}
  2727.  
  2728. - if (command == "CPU") {LogCPUInfo(); return true;}
  2729. + if (command == "CPU") {DEBUG_LogCPUInfo(); return true;}
  2730.  
  2731. if (command == "INTVEC") {
  2732. if (found[0] != 0) {
  2733. @@ -1239,7 +1065,7 @@
  2734.  
  2735. if (command == "INTHAND") {
  2736. if (found[0] != 0) {
  2737. - Bit8u intNr = (Bit8u)GetHexValue(found,found);
  2738. + Bit8u intNr = (Bit8u)DEBUG_GetHexValue(found,found);
  2739. DEBUG_ShowMsg("DEBUG: Set code overview to interrupt handler %X\n",intNr);
  2740. codeViewData.useCS = mem_readw(intNr*4+2);
  2741. codeViewData.useEIP = mem_readw(intNr*4);
  2742. @@ -1249,7 +1075,7 @@
  2743. };
  2744.  
  2745. if(command == "EXTEND") { //Toggle additional data.
  2746. - showExtend = !showExtend;
  2747. + DEBUG_showExtend = !DEBUG_showExtend;
  2748. return true;
  2749. };
  2750.  
  2751. @@ -1262,14 +1088,14 @@
  2752.  
  2753. #if C_HEAVY_DEBUG
  2754. if (command == "HEAVYLOG") { // Create Cpu log file
  2755. - logHeavy = !logHeavy;
  2756. - DEBUG_ShowMsg("DEBUG: Heavy cpu logging %s.\n",logHeavy?"on":"off");
  2757. + DEBUG_logHeavy = !DEBUG_logHeavy;
  2758. + DEBUG_ShowMsg("DEBUG: Heavy cpu logging %s.\n",DEBUG_logHeavy?"on":"off");
  2759. return true;
  2760. };
  2761.  
  2762. if (command == "ZEROPROTECT") { //toggle zero protection
  2763. - zeroProtect = !zeroProtect;
  2764. - DEBUG_ShowMsg("DEBUG: Zero code execution protection %s.\n",zeroProtect?"on":"off");
  2765. + DEBUG_zeroProtect = !DEBUG_zeroProtect;
  2766. + DEBUG_ShowMsg("DEBUG: Zero code execution protection %s.\n",DEBUG_zeroProtect?"on":"off");
  2767. return true;
  2768. };
  2769.  
  2770. @@ -1335,181 +1161,6 @@
  2771. return false;
  2772. };
  2773.  
  2774. -char* AnalyzeInstruction(char* inst, bool saveSelector) {
  2775. - static char result[256];
  2776. -
  2777. - char instu[256];
  2778. - char prefix[3];
  2779. - Bit16u seg;
  2780. -
  2781. - strcpy(instu,inst);
  2782. - upcase(instu);
  2783. -
  2784. - result[0] = 0;
  2785. - char* pos = strchr(instu,'[');
  2786. - if (pos) {
  2787. - // Segment prefix ?
  2788. - if (*(pos-1)==':') {
  2789. - char* segpos = pos-3;
  2790. - prefix[0] = tolower(*segpos);
  2791. - prefix[1] = tolower(*(segpos+1));
  2792. - prefix[2] = 0;
  2793. - seg = (Bit16u)GetHexValue(segpos,segpos);
  2794. - } else {
  2795. - if (strstr(pos,"SP") || strstr(pos,"BP")) {
  2796. - seg = SegValue(ss);
  2797. - strcpy(prefix,"ss");
  2798. - } else {
  2799. - seg = SegValue(ds);
  2800. - strcpy(prefix,"ds");
  2801. - };
  2802. - };
  2803. -
  2804. - pos++;
  2805. - Bit32u adr = GetHexValue(pos,pos);
  2806. - while (*pos!=']') {
  2807. - if (*pos=='+') {
  2808. - pos++;
  2809. - adr += GetHexValue(pos,pos);
  2810. - } else if (*pos=='-') {
  2811. - pos++;
  2812. - adr -= GetHexValue(pos,pos);
  2813. - } else
  2814. - pos++;
  2815. - };
  2816. - Bit32u address = GetAddress(seg,adr);
  2817. - if (!(get_tlb_readhandler(address)->flags & PFLAG_INIT)) {
  2818. - static char outmask[] = "%s:[%04X]=%02X";
  2819. -
  2820. - if (cpu.pmode) outmask[6] = '8';
  2821. - switch (DasmLastOperandSize()) {
  2822. - case 8 : { Bit8u val = mem_readb(address);
  2823. - outmask[12] = '2';
  2824. - sprintf(result,outmask,prefix,adr,val);
  2825. - } break;
  2826. - case 16: { Bit16u val = mem_readw(address);
  2827. - outmask[12] = '4';
  2828. - sprintf(result,outmask,prefix,adr,val);
  2829. - } break;
  2830. - case 32: { Bit32u val = mem_readd(address);
  2831. - outmask[12] = '8';
  2832. - sprintf(result,outmask,prefix,adr,val);
  2833. - } break;
  2834. - }
  2835. - } else {
  2836. - sprintf(result,"[illegal]");
  2837. - }
  2838. - // Variable found ?
  2839. - CDebugVar* var = CDebugVar::FindVar(address);
  2840. - if (var) {
  2841. - // Replace occurence
  2842. - char* pos1 = strchr(inst,'[');
  2843. - char* pos2 = strchr(inst,']');
  2844. - if (pos1 && pos2) {
  2845. - char temp[256];
  2846. - strcpy(temp,pos2); // save end
  2847. - pos1++; *pos1 = 0; // cut after '['
  2848. - strcat(inst,var->GetName()); // add var name
  2849. - strcat(inst,temp); // add end
  2850. - };
  2851. - };
  2852. - // show descriptor info, if available
  2853. - if ((cpu.pmode) && saveSelector) {
  2854. - strcpy(curSelectorName,prefix);
  2855. - };
  2856. - };
  2857. - // If it is a callback add additional info
  2858. - pos = strstr(inst,"callback");
  2859. - if (pos) {
  2860. - pos += 9;
  2861. - Bitu nr = GetHexValue(pos,pos);
  2862. - const char* descr = CALLBACK_GetDescription(nr);
  2863. - if (descr) {
  2864. - strcat(inst," ("); strcat(inst,descr); strcat(inst,")");
  2865. - }
  2866. - };
  2867. - // Must be a jump
  2868. - if (instu[0] == 'J')
  2869. - {
  2870. - bool jmp = false;
  2871. - switch (instu[1]) {
  2872. - case 'A' : { jmp = (get_CF()?false:true) && (get_ZF()?false:true); // JA
  2873. - } break;
  2874. - case 'B' : { if (instu[2] == 'E') {
  2875. - jmp = (get_CF()?true:false) || (get_ZF()?true:false); // JBE
  2876. - } else {
  2877. - jmp = get_CF()?true:false; // JB
  2878. - }
  2879. - } break;
  2880. - case 'C' : { if (instu[2] == 'X') {
  2881. - jmp = reg_cx == 0; // JCXZ
  2882. - } else {
  2883. - jmp = get_CF()?true:false; // JC
  2884. - }
  2885. - } break;
  2886. - case 'E' : { jmp = get_ZF()?true:false; // JE
  2887. - } break;
  2888. - case 'G' : { if (instu[2] == 'E') {
  2889. - jmp = (get_SF()?true:false)==(get_OF()?true:false); // JGE
  2890. - } else {
  2891. - jmp = (get_ZF()?false:true) && ((get_SF()?true:false)==(get_OF()?true:false)); // JG
  2892. - }
  2893. - } break;
  2894. - case 'L' : { if (instu[2] == 'E') {
  2895. - jmp = (get_ZF()?true:false) || ((get_SF()?true:false)!=(get_OF()?true:false)); // JLE
  2896. - } else {
  2897. - jmp = (get_SF()?true:false)!=(get_OF()?true:false); // JL
  2898. - }
  2899. - } break;
  2900. - case 'M' : { jmp = true; // JMP
  2901. - } break;
  2902. - case 'N' : { switch (instu[2]) {
  2903. - case 'B' :
  2904. - case 'C' : { jmp = get_CF()?false:true; // JNB / JNC
  2905. - } break;
  2906. - case 'E' : { jmp = get_ZF()?false:true; // JNE
  2907. - } break;
  2908. - case 'O' : { jmp = get_OF()?false:true; // JNO
  2909. - } break;
  2910. - case 'P' : { jmp = get_PF()?false:true; // JNP
  2911. - } break;
  2912. - case 'S' : { jmp = get_SF()?false:true; // JNS
  2913. - } break;
  2914. - case 'Z' : { jmp = get_ZF()?false:true; // JNZ
  2915. - } break;
  2916. - }
  2917. - } break;
  2918. - case 'O' : { jmp = get_OF()?true:false; // JO
  2919. - } break;
  2920. - case 'P' : { if (instu[2] == 'O') {
  2921. - jmp = get_PF()?false:true; // JPO
  2922. - } else {
  2923. - jmp = get_SF()?true:false; // JP / JPE
  2924. - }
  2925. - } break;
  2926. - case 'S' : { jmp = get_SF()?true:false; // JS
  2927. - } break;
  2928. - case 'Z' : { jmp = get_ZF()?true:false; // JZ
  2929. - } break;
  2930. - }
  2931. - if (jmp) {
  2932. - pos = strchr(instu,'$');
  2933. - if (pos) {
  2934. - pos = strchr(instu,'+');
  2935. - if (pos) {
  2936. - strcpy(result,"(down)");
  2937. - } else {
  2938. - strcpy(result,"(up)");
  2939. - }
  2940. - }
  2941. - } else {
  2942. - sprintf(result,"(no jmp)");
  2943. - }
  2944. - }
  2945. - return result;
  2946. -};
  2947. -
  2948. -
  2949. Bit32u DEBUG_CheckKeys(void) {
  2950. Bits ret=0;
  2951. int key=getch();
  2952. @@ -1548,36 +1201,36 @@
  2953.  
  2954. switch(toupper(key)) {
  2955. case 'D' : // ALT - D: DS:SI
  2956. - dataSeg = SegValue(ds);
  2957. - if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_esi;
  2958. - else dataOfs = reg_si;
  2959. + DEBUG_dataSeg = SegValue(ds);
  2960. + if (cpu.pmode && !(reg_flags & FLAG_VM)) DEBUG_dataOfs = reg_esi;
  2961. + else DEBUG_dataOfs = reg_si;
  2962. break;
  2963. case 'E' : //ALT - E: es:di
  2964. - dataSeg = SegValue(es);
  2965. - if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_edi;
  2966. - else dataOfs = reg_di;
  2967. + DEBUG_dataSeg = SegValue(es);
  2968. + if (cpu.pmode && !(reg_flags & FLAG_VM)) DEBUG_dataOfs = reg_edi;
  2969. + else DEBUG_dataOfs = reg_di;
  2970. break;
  2971. case 'X': //ALT - X: ds:dx
  2972. - dataSeg = SegValue(ds);
  2973. - if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_edx;
  2974. - else dataOfs = reg_dx;
  2975. + DEBUG_dataSeg = SegValue(ds);
  2976. + if (cpu.pmode && !(reg_flags & FLAG_VM)) DEBUG_dataOfs = reg_edx;
  2977. + else DEBUG_dataOfs = reg_dx;
  2978. break;
  2979. case 'B' : //ALT -B: es:bx
  2980. - dataSeg = SegValue(es);
  2981. - if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_ebx;
  2982. - else dataOfs = reg_bx;
  2983. + DEBUG_dataSeg = SegValue(es);
  2984. + if (cpu.pmode && !(reg_flags & FLAG_VM)) DEBUG_dataOfs = reg_ebx;
  2985. + else DEBUG_dataOfs = reg_bx;
  2986. break;
  2987. case 'S': //ALT - S: ss:sp
  2988. - dataSeg = SegValue(ss);
  2989. - if (cpu.pmode && !(reg_flags & FLAG_VM)) dataOfs = reg_esp;
  2990. - else dataOfs = reg_sp;
  2991. + DEBUG_dataSeg = SegValue(ss);
  2992. + if (cpu.pmode && !(reg_flags & FLAG_VM)) DEBUG_dataOfs = reg_esp;
  2993. + else DEBUG_dataOfs = reg_sp;
  2994. break;
  2995. default:
  2996. break;
  2997. }
  2998. break;
  2999. - case KEY_PPAGE : dataOfs -= 16; break;
  3000. - case KEY_NPAGE : dataOfs += 16; break;
  3001. + case KEY_PPAGE : DEBUG_dataOfs -= 16; break;
  3002. + case KEY_NPAGE : DEBUG_dataOfs += 16; break;
  3003.  
  3004. case KEY_DOWN: // down
  3005. if (codeViewData.cursorPos<9) codeViewData.cursorPos++;
  3006. @@ -1592,7 +1245,7 @@
  3007. Bit32u newEIP = codeViewData.useEIP - 1;
  3008. if(codeViewData.useEIP) {
  3009. for (; bytes < 10; bytes++) {
  3010. - PhysPt start = GetAddress(codeViewData.useCS,newEIP);
  3011. + PhysPt start = DEBUG_GetAddress(codeViewData.useCS,newEIP);
  3012. size = DasmI386(dline, start, newEIP, cpu.code.big);
  3013. if(codeViewData.useEIP == newEIP+size) break;
  3014. newEIP--;
  3015. @@ -1645,7 +1298,7 @@
  3016. DOSBOX_SetNormalLoop();
  3017. break;
  3018. case KEY_F(9): // Set/Remove Breakpoint
  3019. - { PhysPt ptr = GetAddress(codeViewData.cursorSeg,codeViewData.cursorOfs);
  3020. + { PhysPt ptr = DEBUG_GetAddress(codeViewData.cursorSeg,codeViewData.cursorOfs);
  3021. if (CBreakpoint::IsBreakpoint(ptr)) {
  3022. CBreakpoint::DeleteBreakpoint(ptr);
  3023. DEBUG_ShowMsg("DEBUG: Breakpoint deletion success.\n");
  3024. @@ -1659,7 +1312,7 @@
  3025. case KEY_F(10): // Step over inst
  3026. if (StepOver()) return 0;
  3027. else {
  3028. - exitLoop = false;
  3029. + DEBUG_exitLoop = false;
  3030. skipFirstInstruction = true; // for heavy debugger
  3031. CPU_Cycles = 1;
  3032. ret=(*cpudecoder)();
  3033. @@ -1668,7 +1321,7 @@
  3034. }
  3035. break;
  3036. case KEY_F(11): // trace into
  3037. - exitLoop = false;
  3038. + DEBUG_exitLoop = false;
  3039. skipFirstInstruction = true; // for heavy debugger
  3040. CPU_Cycles = 1;
  3041. ret = (*cpudecoder)();
  3042. @@ -1730,7 +1383,7 @@
  3043. else
  3044. ret = (*CallBack_Handlers[ret])();
  3045. if (ret) {
  3046. - exitLoop=true;
  3047. + DEBUG_exitLoop=true;
  3048. CPU_Cycles=CPU_CycleLeft=0;
  3049. return ret;
  3050. }
  3051. @@ -1785,240 +1438,8 @@
  3052. PIC_ActivateIRQ(0);
  3053. }
  3054.  
  3055. -// Display the content of the MCB chain starting with the MCB at the specified segment.
  3056. -static void LogMCBChain(Bit16u mcb_segment) {
  3057. - DOS_MCB mcb(mcb_segment);
  3058. - char filename[9]; // 8 characters plus a terminating NUL
  3059. - const char *psp_seg_note;
  3060. - PhysPt dataAddr = PhysMake(dataSeg,dataOfs);// location being viewed in the "Data Overview"
  3061.  
  3062. - // loop forever, breaking out of the loop once we've processed the last MCB
  3063. - while (true) {
  3064. - // verify that the type field is valid
  3065. - if (mcb.GetType()!=0x4d && mcb.GetType()!=0x5a) {
  3066. - LOG(LOG_MISC,LOG_ERROR)("MCB chain broken at %04X:0000!",mcb_segment);
  3067. - return;
  3068. - }
  3069.  
  3070. - mcb.GetFileName(filename);
  3071. -
  3072. - // some PSP segment values have special meanings
  3073. - switch (mcb.GetPSPSeg()) {
  3074. - case MCB_FREE:
  3075. - psp_seg_note = "(free)";
  3076. - break;
  3077. - case MCB_DOS:
  3078. - psp_seg_note = "(DOS)";
  3079. - break;
  3080. - default:
  3081. - psp_seg_note = "";
  3082. - }
  3083. -
  3084. - LOG(LOG_MISC,LOG_ERROR)(" %04X %12u %04X %-7s %s",mcb_segment,mcb.GetSize() << 4,mcb.GetPSPSeg(), psp_seg_note, filename);
  3085. -
  3086. - // print a message if dataAddr is within this MCB's memory range
  3087. - PhysPt mcbStartAddr = PhysMake(mcb_segment+1,0);
  3088. - PhysPt mcbEndAddr = PhysMake(mcb_segment+1+mcb.GetSize(),0);
  3089. - if (dataAddr >= mcbStartAddr && dataAddr < mcbEndAddr) {
  3090. - LOG(LOG_MISC,LOG_ERROR)(" (data addr %04hX:%04X is %u bytes past this MCB)",dataSeg,dataOfs,dataAddr - mcbStartAddr);
  3091. - }
  3092. -
  3093. - // if we've just processed the last MCB in the chain, break out of the loop
  3094. - if (mcb.GetType()==0x5a) {
  3095. - break;
  3096. - }
  3097. - // else, move to the next MCB in the chain
  3098. - mcb_segment+=mcb.GetSize()+1;
  3099. - mcb.SetPt(mcb_segment);
  3100. - }
  3101. -}
  3102. -
  3103. -// Display the content of all Memory Control Blocks.
  3104. -static void LogMCBS(void)
  3105. -{
  3106. - LOG(LOG_MISC,LOG_ERROR)("MCB Seg Size (bytes) PSP Seg (notes) Filename");
  3107. - LOG(LOG_MISC,LOG_ERROR)("Conventional memory:");
  3108. - LogMCBChain(dos.firstMCB);
  3109. -
  3110. - LOG(LOG_MISC,LOG_ERROR)("Upper memory:");
  3111. - LogMCBChain(dos_infoblock.GetStartOfUMBChain());
  3112. -}
  3113. -
  3114. -static void LogGDT(void)
  3115. -{
  3116. - char out1[512];
  3117. - Descriptor desc;
  3118. - Bitu length = cpu.gdt.GetLimit();
  3119. - PhysPt address = cpu.gdt.GetBase();
  3120. - PhysPt max = address + length;
  3121. - Bitu i = 0;
  3122. - LOG(LOG_MISC,LOG_ERROR)("GDT Base:%08X Limit:%08X",address,length);
  3123. - while (address<max) {
  3124. - desc.Load(address);
  3125. - sprintf(out1,"%04X: b:%08X type: %02X parbg",(i<<3),desc.GetBase(),desc.saved.seg.type);
  3126. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3127. - sprintf(out1," l:%08X dpl : %01X %1X%1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.big,desc.saved.seg.g);
  3128. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3129. - address+=8; i++;
  3130. - };
  3131. -};
  3132. -
  3133. -static void LogLDT(void) {
  3134. - char out1[512];
  3135. - Descriptor desc;
  3136. - Bitu ldtSelector = cpu.gdt.SLDT();
  3137. - if (!cpu.gdt.GetDescriptor(ldtSelector,desc)) return;
  3138. - Bitu length = desc.GetLimit();
  3139. - PhysPt address = desc.GetBase();
  3140. - PhysPt max = address + length;
  3141. - Bitu i = 0;
  3142. - LOG(LOG_MISC,LOG_ERROR)("LDT Base:%08X Limit:%08X",address,length);
  3143. - while (address<max) {
  3144. - desc.Load(address);
  3145. - sprintf(out1,"%04X: b:%08X type: %02X parbg",(i<<3)|4,desc.GetBase(),desc.saved.seg.type);
  3146. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3147. - sprintf(out1," l:%08X dpl : %01X %1X%1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.big,desc.saved.seg.g);
  3148. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3149. - address+=8; i++;
  3150. - };
  3151. -};
  3152. -
  3153. -static void LogIDT(void) {
  3154. - char out1[512];
  3155. - Descriptor desc;
  3156. - Bitu address = 0;
  3157. - while (address<256*8) {
  3158. - if (cpu.idt.GetDescriptor(address,desc)) {
  3159. - sprintf(out1,"%04X: sel:%04X off:%02X",address/8,desc.GetSelector(),desc.GetOffset());
  3160. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3161. - }
  3162. - address+=8;
  3163. - };
  3164. -};
  3165. -
  3166. -void LogPages(char* selname) {
  3167. - char out1[512];
  3168. - if (paging.enabled) {
  3169. - Bitu sel = GetHexValue(selname,selname);
  3170. - if ((sel==0x00) && ((*selname==0) || (*selname=='*'))) {
  3171. - for (int i=0; i<0xfffff; i++) {
  3172. - Bitu table_addr=(paging.base.page<<12)+(i >> 10)*4;
  3173. - X86PageEntry table;
  3174. - table.load=phys_readd(table_addr);
  3175. - if (table.block.p) {
  3176. - X86PageEntry entry;
  3177. - Bitu entry_addr=(table.block.base<<12)+(i & 0x3ff)*4;
  3178. - entry.load=phys_readd(entry_addr);
  3179. - if (entry.block.p) {
  3180. - sprintf(out1,"page %05Xxxx -> %04Xxxx flags [uw] %x:%x::%x:%x [d=%x|a=%x]",
  3181. - i,entry.block.base,entry.block.us,table.block.us,
  3182. - entry.block.wr,table.block.wr,entry.block.d,entry.block.a);
  3183. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3184. - }
  3185. - }
  3186. - }
  3187. - } else {
  3188. - Bitu table_addr=(paging.base.page<<12)+(sel >> 10)*4;
  3189. - X86PageEntry table;
  3190. - table.load=phys_readd(table_addr);
  3191. - if (table.block.p) {
  3192. - X86PageEntry entry;
  3193. - Bitu entry_addr=(table.block.base<<12)+(sel & 0x3ff)*4;
  3194. - entry.load=phys_readd(entry_addr);
  3195. - sprintf(out1,"page %05Xxxx -> %04Xxxx flags [puw] %x:%x::%x:%x::%x:%x",sel,entry.block.base,entry.block.p,table.block.p,entry.block.us,table.block.us,entry.block.wr,table.block.wr);
  3196. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3197. - } else {
  3198. - sprintf(out1,"pagetable %03X not present, flags [puw] %x::%x::%x",(sel >> 10),table.block.p,table.block.us,table.block.wr);
  3199. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3200. - }
  3201. - }
  3202. - }
  3203. -};
  3204. -
  3205. -static void LogCPUInfo(void) {
  3206. - char out1[512];
  3207. - sprintf(out1,"cr0:%08X cr2:%08X cr3:%08X cpl=%x",cpu.cr0,paging.cr2,paging.cr3,cpu.cpl);
  3208. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3209. - sprintf(out1,"eflags:%08X [vm=%x iopl=%x nt=%x]",reg_flags,GETFLAG(VM)>>17,GETFLAG(IOPL)>>12,GETFLAG(NT)>>14);
  3210. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3211. - sprintf(out1,"GDT base=%08X limit=%08X",cpu.gdt.GetBase(),cpu.gdt.GetLimit());
  3212. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3213. - sprintf(out1,"IDT base=%08X limit=%08X",cpu.idt.GetBase(),cpu.idt.GetLimit());
  3214. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3215. -
  3216. - Bitu sel=CPU_STR();
  3217. - Descriptor desc;
  3218. - if (cpu.gdt.GetDescriptor(sel,desc)) {
  3219. - sprintf(out1,"TR selector=%04X, base=%08X limit=%08X*%X",sel,desc.GetBase(),desc.GetLimit(),desc.saved.seg.g?0x4000:1);
  3220. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3221. - }
  3222. - sel=CPU_SLDT();
  3223. - if (cpu.gdt.GetDescriptor(sel,desc)) {
  3224. - sprintf(out1,"LDT selector=%04X, base=%08X limit=%08X*%X",sel,desc.GetBase(),desc.GetLimit(),desc.saved.seg.g?0x4000:1);
  3225. - LOG(LOG_MISC,LOG_ERROR)(out1);
  3226. - }
  3227. -};
  3228. -
  3229. -#if C_HEAVY_DEBUG
  3230. -static void LogInstruction(Bit16u segValue, Bit32u eipValue, ofstream& out) {
  3231. - static char empty[23] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 };
  3232. -
  3233. - PhysPt start = GetAddress(segValue,eipValue);
  3234. - char dline[200];Bitu size;
  3235. - size = DasmI386(dline, start, reg_eip, cpu.code.big);
  3236. - char* res = empty;
  3237. - if (showExtend && (cpuLogType > 0) ) {
  3238. - res = AnalyzeInstruction(dline,false);
  3239. - if (!res || !(*res)) res = empty;
  3240. - Bitu reslen = strlen(res);
  3241. - if (reslen<22) for (Bitu i=0; i<22-reslen; i++) res[reslen+i] = ' '; res[22] = 0;
  3242. - };
  3243. - Bitu len = strlen(dline);
  3244. - if (len<30) for (Bitu i=0; i<30-len; i++) dline[len + i] = ' '; dline[30] = 0;
  3245. -
  3246. - // Get register values
  3247. -
  3248. - if(cpuLogType == 0) {
  3249. - out << setw(4) << SegValue(cs) << ":" << setw(4) << reg_eip << " " << dline;
  3250. - } else if (cpuLogType == 1) {
  3251. - out << setw(4) << SegValue(cs) << ":" << setw(8) << reg_eip << " " << dline << " " << res;
  3252. - } else if (cpuLogType == 2) {
  3253. - char ibytes[200]=""; char tmpc[200];
  3254. - for (Bitu i=0; i<size; i++) {
  3255. - Bit8u value;
  3256. - if (mem_readb_checked(start+i,&value)) sprintf(tmpc,"%s","?? ");
  3257. - else sprintf(tmpc,"%02X ",value);
  3258. - strcat(ibytes,tmpc);
  3259. - }
  3260. - len = strlen(ibytes);
  3261. - if (len<21) { for (Bitu i=0; i<21-len; i++) ibytes[len + i] =' '; ibytes[21]=0;} //NOTE THE BRACKETS
  3262. - out << setw(4) << SegValue(cs) << ":" << setw(8) << reg_eip << " " << dline << " " << res << " " << ibytes;
  3263. - }
  3264. -
  3265. - out << " EAX:" << setw(8) << reg_eax << " EBX:" << setw(8) << reg_ebx
  3266. - << " ECX:" << setw(8) << reg_ecx << " EDX:" << setw(8) << reg_edx
  3267. - << " ESI:" << setw(8) << reg_esi << " EDI:" << setw(8) << reg_edi
  3268. - << " EBP:" << setw(8) << reg_ebp << " ESP:" << setw(8) << reg_esp
  3269. - << " DS:" << setw(4) << SegValue(ds)<< " ES:" << setw(4) << SegValue(es);
  3270. -
  3271. - if(cpuLogType == 0) {
  3272. - out << " SS:" << setw(4) << SegValue(ss) << " C" << (get_CF()>0) << " Z" << (get_ZF()>0)
  3273. - << " S" << (get_SF()>0) << " O" << (get_OF()>0) << " I" << GETFLAGBOOL(IF);
  3274. - } else {
  3275. - out << " FS:" << setw(4) << SegValue(fs) << " GS:" << setw(4) << SegValue(gs)
  3276. - << " SS:" << setw(4) << SegValue(ss)
  3277. - << " CF:" << (get_CF()>0) << " ZF:" << (get_ZF()>0) << " SF:" << (get_SF()>0)
  3278. - << " OF:" << (get_OF()>0) << " AF:" << (get_AF()>0) << " PF:" << (get_PF()>0)
  3279. - << " IF:" << GETFLAGBOOL(IF);
  3280. - }
  3281. - if(cpuLogType == 2) {
  3282. - out << " TF:" << GETFLAGBOOL(TF) << " VM:" << GETFLAGBOOL(VM) <<" FLG:" << setw(8) << reg_flags
  3283. - << " CR0:" << setw(8) << cpu.cr0;
  3284. - }
  3285. - out << endl;
  3286. -};
  3287. -#endif
  3288. -
  3289. // DEBUG.COM stuff
  3290.  
  3291. class DEBUG : public Program {
  3292. @@ -2088,7 +1509,7 @@
  3293.  
  3294. Bitu DEBUG_EnableDebugger(void)
  3295. {
  3296. - exitLoop = true;
  3297. + DEBUG_exitLoop = true;
  3298. DEBUG_Enable(true);
  3299. CPU_Cycles=CPU_CycleLeft=0;
  3300. return 0;
  3301. @@ -2128,7 +1549,7 @@
  3302. #endif
  3303. }
  3304.  
  3305. -Bitu debugCallback;
  3306. +Bitu DEBUG_debugCallback;
  3307.  
  3308. void DEBUG_Init(Section* sec) {
  3309.  
  3310. @@ -2141,14 +1562,20 @@
  3311. /* setup debug.com */
  3312. PROGRAMS_MakeFile("DEBUG.COM",DEBUG_ProgramStart);
  3313. /* Setup callback */
  3314. - debugCallback=CALLBACK_Allocate();
  3315. - CALLBACK_Setup(debugCallback,DEBUG_EnableDebugger,CB_RETF,"debugger");
  3316. + DEBUG_debugCallback=CALLBACK_Allocate();
  3317. + CALLBACK_Setup(DEBUG_debugCallback,DEBUG_EnableDebugger,CB_RETF,"debugger");
  3318. /* shutdown function */
  3319. sec->AddDestroyFunction(&DEBUG_ShutDown);
  3320. }
  3321.  
  3322. // DEBUGGING VAR STUFF
  3323.  
  3324. +CDebugVar::CDebugVar(char* _name, PhysPt _adr)
  3325. +{
  3326. + adr=_adr;
  3327. + safe_strncpy(name,_name,16);
  3328. +};
  3329. +
  3330. void CDebugVar::InsertVariable(char* name, PhysPt adr)
  3331. {
  3332. varList.push_back(new CDebugVar(name,adr));
  3333. @@ -2237,7 +1664,7 @@
  3334. sprintf(buffer,"%04X:%04X ",seg,ofs1);
  3335. for (Bit16u x=0; x<16; x++) {
  3336. Bit8u value;
  3337. - if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"%s","?? ");
  3338. + if (mem_readb_checked(DEBUG_GetAddress(seg,ofs1+x),&value)) sprintf(temp,"%s","?? ");
  3339. else sprintf(temp,"%02X ",value);
  3340. strcat(buffer,temp);
  3341. }
  3342. @@ -2250,7 +1677,7 @@
  3343. sprintf(buffer,"%04X:%04X ",seg,ofs1);
  3344. for (Bit16u x=0; x<num; x++) {
  3345. Bit8u value;
  3346. - if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"%s","?? ");
  3347. + if (mem_readb_checked(DEBUG_GetAddress(seg,ofs1+x),&value)) sprintf(temp,"%s","?? ");
  3348. else sprintf(temp,"%02X ",value);
  3349. strcat(buffer,temp);
  3350. }
  3351. @@ -2269,7 +1696,7 @@
  3352.  
  3353. for (Bitu x = 0; x < num;x++) {
  3354. Bit8u val;
  3355. - if (mem_readb_checked(GetAddress(seg,ofs1+x),&val)) val=0;
  3356. + if (mem_readb_checked(DEBUG_GetAddress(seg,ofs1+x),&val)) val=0;
  3357. fwrite(&val,1,1,f);
  3358. }
  3359.  
  3360. @@ -2329,144 +1756,24 @@
  3361.  
  3362. #if C_HEAVY_DEBUG
  3363.  
  3364. -const Bit32u LOGCPUMAX = 20000;
  3365. -
  3366. -static Bit32u logCount = 0;
  3367. -
  3368. -struct TLogInst {
  3369. - Bit16u s_cs;
  3370. - Bit32u eip;
  3371. - Bit32u eax;
  3372. - Bit32u ebx;
  3373. - Bit32u ecx;
  3374. - Bit32u edx;
  3375. - Bit32u esi;
  3376. - Bit32u edi;
  3377. - Bit32u ebp;
  3378. - Bit32u esp;
  3379. - Bit16u s_ds;
  3380. - Bit16u s_es;
  3381. - Bit16u s_fs;
  3382. - Bit16u s_gs;
  3383. - Bit16u s_ss;
  3384. - bool c;
  3385. - bool z;
  3386. - bool s;
  3387. - bool o;
  3388. - bool a;
  3389. - bool p;
  3390. - bool i;
  3391. - char dline[31];
  3392. - char res[23];
  3393. -};
  3394. -
  3395. -TLogInst logInst[LOGCPUMAX];
  3396. -
  3397. -void DEBUG_HeavyLogInstruction(void) {
  3398. -
  3399. - static char empty[23] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 };
  3400. -
  3401. - PhysPt start = GetAddress(SegValue(cs),reg_eip);
  3402. - char dline[200];
  3403. - DasmI386(dline, start, reg_eip, cpu.code.big);
  3404. - char* res = empty;
  3405. - if (showExtend) {
  3406. - res = AnalyzeInstruction(dline,false);
  3407. - if (!res || !(*res)) res = empty;
  3408. - Bitu reslen = strlen(res);
  3409. - if (reslen<22) for (Bitu i=0; i<22-reslen; i++) res[reslen+i] = ' '; res[22] = 0;
  3410. - };
  3411. -
  3412. - Bitu len = strlen(dline);
  3413. - if (len < 30) for (Bitu i=0; i < 30-len; i++) dline[len+i] = ' ';
  3414. - dline[30] = 0;
  3415. -
  3416. - TLogInst & inst = logInst[logCount];
  3417. - strcpy(inst.dline,dline);
  3418. - inst.s_cs = SegValue(cs);
  3419. - inst.eip = reg_eip;
  3420. - strcpy(inst.res,res);
  3421. - inst.eax = reg_eax;
  3422. - inst.ebx = reg_ebx;
  3423. - inst.ecx = reg_ecx;
  3424. - inst.edx = reg_edx;
  3425. - inst.esi = reg_esi;
  3426. - inst.edi = reg_edi;
  3427. - inst.ebp = reg_ebp;
  3428. - inst.esp = reg_esp;
  3429. - inst.s_ds = SegValue(ds);
  3430. - inst.s_es = SegValue(es);
  3431. - inst.s_fs = SegValue(fs);
  3432. - inst.s_gs = SegValue(gs);
  3433. - inst.s_ss = SegValue(ss);
  3434. - inst.c = get_CF()>0;
  3435. - inst.z = get_ZF()>0;
  3436. - inst.s = get_SF()>0;
  3437. - inst.o = get_OF()>0;
  3438. - inst.a = get_AF()>0;
  3439. - inst.p = get_PF()>0;
  3440. - inst.i = GETFLAGBOOL(IF);
  3441. -
  3442. - if (++logCount >= LOGCPUMAX) logCount = 0;
  3443. -};
  3444. -
  3445. -void DEBUG_HeavyWriteLogInstruction(void) {
  3446. - if (!logHeavy) return;
  3447. - logHeavy = false;
  3448. -
  3449. - DEBUG_ShowMsg("DEBUG: Creating cpu log LOGCPU_INT_CD.TXT\n");
  3450. -
  3451. - ofstream out("LOGCPU_INT_CD.TXT");
  3452. - if (!out.is_open()) {
  3453. - DEBUG_ShowMsg("DEBUG: Failed.\n");
  3454. - return;
  3455. - }
  3456. - out << hex << noshowbase << setfill('0') << uppercase;
  3457. - Bit32u startLog = logCount;
  3458. - do {
  3459. - // Write Instructions
  3460. - TLogInst & inst = logInst[startLog];
  3461. - out << setw(4) << inst.s_cs << ":" << setw(8) << inst.eip << " "
  3462. - << inst.dline << " " << inst.res << " EAX:" << setw(8)<< inst.eax
  3463. - << " EBX:" << setw(8) << inst.ebx << " ECX:" << setw(8) << inst.ecx
  3464. - << " EDX:" << setw(8) << inst.edx << " ESI:" << setw(8) << inst.esi
  3465. - << " EDI:" << setw(8) << inst.edi << " EBP:" << setw(8) << inst.ebp
  3466. - << " ESP:" << setw(8) << inst.esp << " DS:" << setw(4) << inst.s_ds
  3467. - << " ES:" << setw(4) << inst.s_es<< " FS:" << setw(4) << inst.s_fs
  3468. - << " GS:" << setw(4) << inst.s_gs<< " SS:" << setw(4) << inst.s_ss
  3469. - << " CF:" << inst.c << " ZF:" << inst.z << " SF:" << inst.s
  3470. - << " OF:" << inst.o << " AF:" << inst.a << " PF:" << inst.p
  3471. - << " IF:" << inst.i << endl;
  3472. -
  3473. -/* fprintf(f,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X IF:%01X\n",
  3474. - logInst[startLog].s_cs,logInst[startLog].eip,logInst[startLog].dline,logInst[startLog].res,logInst[startLog].eax,logInst[startLog].ebx,logInst[startLog].ecx,logInst[startLog].edx,logInst[startLog].esi,logInst[startLog].edi,logInst[startLog].ebp,logInst[startLog].esp,
  3475. - logInst[startLog].s_ds,logInst[startLog].s_es,logInst[startLog].s_fs,logInst[startLog].s_gs,logInst[startLog].s_ss,
  3476. - logInst[startLog].c,logInst[startLog].z,logInst[startLog].s,logInst[startLog].o,logInst[startLog].a,logInst[startLog].p,logInst[startLog].i);*/
  3477. - if (++startLog >= LOGCPUMAX) startLog = 0;
  3478. - } while (startLog != logCount);
  3479. -
  3480. - out.close();
  3481. - DEBUG_ShowMsg("DEBUG: Done.\n");
  3482. -};
  3483. -
  3484. bool DEBUG_HeavyIsBreakpoint(void) {
  3485. static Bitu zero_count = 0;
  3486. - if (cpuLog) {
  3487. - if (cpuLogCounter>0) {
  3488. - LogInstruction(SegValue(cs),reg_eip,cpuLogFile);
  3489. - cpuLogCounter--;
  3490. + if (DEBUG_cpuLog) {
  3491. + if (DEBUG_cpuLogCounter>0) {
  3492. + DEBUG_LogInstruction(SegValue(cs),reg_eip,DEBUG_cpuLogFile);
  3493. + DEBUG_cpuLogCounter--;
  3494. }
  3495. - if (cpuLogCounter<=0) {
  3496. - cpuLogFile.close();
  3497. + if (DEBUG_cpuLogCounter<=0) {
  3498. + DEBUG_cpuLogFile.close();
  3499. DEBUG_ShowMsg("DEBUG: cpu log LOGCPU.TXT created\n");
  3500. - cpuLog = false;
  3501. + DEBUG_cpuLog = false;
  3502. DEBUG_EnableDebugger();
  3503. return true;
  3504. }
  3505. }
  3506. - // LogInstruction
  3507. - if (logHeavy) DEBUG_HeavyLogInstruction();
  3508. - if (zeroProtect) {
  3509. + // DEBUG_LogInstruction
  3510. + if (DEBUG_logHeavy) DEBUG_HeavyLogInstruction();
  3511. + if (DEBUG_zeroProtect) {
  3512. Bit32u value=0;
  3513. if (!mem_readd_checked(SegPhys(cs)+reg_eip,&value)) {
  3514. if (value == 0) zero_count++;
  3515. Index: src/debug/debug_disasm.cpp
  3516. ===================================================================
  3517. --- src/debug/debug_disasm.cpp (revision 3761)
  3518. +++ src/debug/debug_disasm.cpp (working copy)
  3519. @@ -63,7 +63,7 @@
  3520.  
  3521. */
  3522. #include "dosbox.h"
  3523. -#if C_DEBUG
  3524. +#if C_DEBUG || C_GDBSERVER
  3525. #include <stdio.h>
  3526. #include <string.h>
  3527. #include <stdarg.h>
  3528. Index: src/debug/debug_log.cpp
  3529. ===================================================================
  3530. --- src/debug/debug_log.cpp (revision 0)
  3531. +++ src/debug/debug_log.cpp (revision 0)
  3532. @@ -0,0 +1,502 @@
  3533. +/*
  3534. + * Copyright (C) 2002-2011 The DOSBox Team
  3535. + *
  3536. + * This program is free software; you can redistribute it and/or modify
  3537. + * it under the terms of the GNU General Public License as published by
  3538. + * the Free Software Foundation; either version 2 of the License, or
  3539. + * (at your option) any later version.
  3540. + *
  3541. + * This program is distributed in the hope that it will be useful,
  3542. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3543. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3544. + * GNU General Public License for more details.
  3545. + *
  3546. + * You should have received a copy of the GNU General Public License
  3547. + * along with this program; if not, write to the Free Software
  3548. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  3549. + */
  3550. +
  3551. +#include "dosbox.h"
  3552. +#if C_DEBUG || C_GDBSERVER
  3553. +
  3554. +#include <string.h>
  3555. +#include <list>
  3556. +#include <ctype.h>
  3557. +#include <fstream>
  3558. +#include <iomanip>
  3559. +#include <string>
  3560. +#include <sstream>
  3561. +using namespace std;
  3562. +
  3563. +#include "control.h"
  3564. +#include "debug.h"
  3565. +#include "cross.h" //snprintf
  3566. +#include "cpu.h"
  3567. +#include "video.h"
  3568. +#include "pic.h"
  3569. +#include "mapper.h"
  3570. +#include "cpu.h"
  3571. +#include "callback.h"
  3572. +#include "inout.h"
  3573. +#include "mixer.h"
  3574. +#include "timer.h"
  3575. +#include "paging.h"
  3576. +#include "support.h"
  3577. +#include "shell.h"
  3578. +#include "programs.h"
  3579. +#include "debug_inc.h"
  3580. +#include "../cpu/lazyflags.h"
  3581. +#include "keyboard.h"
  3582. +#include "setup.h"
  3583. +
  3584. +// Heavy Debugging Vars for logging
  3585. +#if C_HEAVY_DEBUG || C_GDBSERVER
  3586. +ofstream DEBUG_cpuLogFile;
  3587. +bool DEBUG_cpuLog = false;
  3588. +int DEBUG_cpuLogCounter = 0;
  3589. +int DEBUG_cpuLogType = 1; // log detail
  3590. +bool DEBUG_zeroProtect = false;
  3591. +bool DEBUG_logHeavy = false;
  3592. +#endif
  3593. +
  3594. +bool DEBUG_showExtend = true;
  3595. +
  3596. +// Display the content of the MCB chain starting with the MCB at the specified segment.
  3597. +void DEBUG_LogMCBChain(Bit16u mcb_segment) {
  3598. + DOS_MCB mcb(mcb_segment);
  3599. + char filename[9]; // 8 characters plus a terminating NUL
  3600. + const char *psp_seg_note;
  3601. + PhysPt dataAddr = PhysMake(DEBUG_dataSeg,DEBUG_dataOfs);// location being viewed in the "Data Overview"
  3602. +
  3603. + // loop forever, breaking out of the loop once we've processed the last MCB
  3604. + while (true) {
  3605. + // verify that the type field is valid
  3606. + if (mcb.GetType()!=0x4d && mcb.GetType()!=0x5a) {
  3607. + LOG(LOG_MISC,LOG_ERROR)("MCB chain broken at %04X:0000!",mcb_segment);
  3608. + return;
  3609. + }
  3610. +
  3611. + mcb.GetFileName(filename);
  3612. +
  3613. + // some PSP segment values have special meanings
  3614. + switch (mcb.GetPSPSeg()) {
  3615. + case MCB_FREE:
  3616. + psp_seg_note = "(free)";
  3617. + break;
  3618. + case MCB_DOS:
  3619. + psp_seg_note = "(DOS)";
  3620. + break;
  3621. + default:
  3622. + psp_seg_note = "";
  3623. + }
  3624. +
  3625. + LOG(LOG_MISC,LOG_ERROR)(" %04X %12u %04X %-7s %s",mcb_segment,mcb.GetSize() << 4,mcb.GetPSPSeg(), psp_seg_note, filename);
  3626. +
  3627. + // print a message if dataAddr is within this MCB's memory range
  3628. + PhysPt mcbStartAddr = PhysMake(mcb_segment+1,0);
  3629. + PhysPt mcbEndAddr = PhysMake(mcb_segment+1+mcb.GetSize(),0);
  3630. + if (dataAddr >= mcbStartAddr && dataAddr < mcbEndAddr) {
  3631. + LOG(LOG_MISC,LOG_ERROR)(" (data addr %04hX:%04X is %u bytes past this MCB)",DEBUG_dataSeg,DEBUG_dataOfs,dataAddr - mcbStartAddr);
  3632. + }
  3633. +
  3634. + // if we've just processed the last MCB in the chain, break out of the loop
  3635. + if (mcb.GetType()==0x5a) {
  3636. + break;
  3637. + }
  3638. + // else, move to the next MCB in the chain
  3639. + mcb_segment+=mcb.GetSize()+1;
  3640. + mcb.SetPt(mcb_segment);
  3641. + }
  3642. +}
  3643. +
  3644. +// Display the content of all Memory Control Blocks.
  3645. +void DEBUG_LogMCBS(void)
  3646. +{
  3647. + LOG(LOG_MISC,LOG_ERROR)("MCB Seg Size (bytes) PSP Seg (notes) Filename");
  3648. + LOG(LOG_MISC,LOG_ERROR)("Conventional memory:");
  3649. + DEBUG_LogMCBChain(dos.firstMCB);
  3650. +
  3651. + LOG(LOG_MISC,LOG_ERROR)("Upper memory:");
  3652. + DEBUG_LogMCBChain(dos_infoblock.GetStartOfUMBChain());
  3653. +}
  3654. +
  3655. +void DEBUG_LogGDT(void)
  3656. +{
  3657. + char out1[512];
  3658. + Descriptor desc;
  3659. + Bitu length = cpu.gdt.GetLimit();
  3660. + PhysPt address = cpu.gdt.GetBase();
  3661. + PhysPt max = address + length;
  3662. + Bitu i = 0;
  3663. + LOG(LOG_MISC,LOG_ERROR)("GDT Base:%08X Limit:%08X",address,length);
  3664. + while (address<max) {
  3665. + desc.Load(address);
  3666. + sprintf(out1,"%04X: b:%08X type: %02X parbg",(i<<3),desc.GetBase(),desc.saved.seg.type);
  3667. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3668. + sprintf(out1," l:%08X dpl : %01X %1X%1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.big,desc.saved.seg.g);
  3669. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3670. + address+=8; i++;
  3671. + };
  3672. +};
  3673. +
  3674. +void DEBUG_LogLDT(void) {
  3675. + char out1[512];
  3676. + Descriptor desc;
  3677. + Bitu ldtSelector = cpu.gdt.SLDT();
  3678. + if (!cpu.gdt.GetDescriptor(ldtSelector,desc)) return;
  3679. + Bitu length = desc.GetLimit();
  3680. + PhysPt address = desc.GetBase();
  3681. + PhysPt max = address + length;
  3682. + Bitu i = 0;
  3683. + LOG(LOG_MISC,LOG_ERROR)("LDT Base:%08X Limit:%08X",address,length);
  3684. + while (address<max) {
  3685. + desc.Load(address);
  3686. + sprintf(out1,"%04X: b:%08X type: %02X parbg",(i<<3)|4,desc.GetBase(),desc.saved.seg.type);
  3687. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3688. + sprintf(out1," l:%08X dpl : %01X %1X%1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.big,desc.saved.seg.g);
  3689. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3690. + address+=8; i++;
  3691. + };
  3692. +};
  3693. +
  3694. +void DEBUG_LogIDT(void) {
  3695. + char out1[512];
  3696. + Descriptor desc;
  3697. + Bitu address = 0;
  3698. + while (address<256*8) {
  3699. + if (cpu.idt.GetDescriptor(address,desc)) {
  3700. + sprintf(out1,"%04X: sel:%04X off:%02X",address/8,desc.GetSelector(),desc.GetOffset());
  3701. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3702. + }
  3703. + address+=8;
  3704. + };
  3705. +};
  3706. +
  3707. +void DEBUG_LogPages(char* selname) {
  3708. + char out1[512];
  3709. + if (paging.enabled) {
  3710. + Bitu sel = DEBUG_GetHexValue(selname,selname);
  3711. + if ((sel==0x00) && ((*selname==0) || (*selname=='*'))) {
  3712. + for (int i=0; i<0xfffff; i++) {
  3713. + Bitu table_addr=(paging.base.page<<12)+(i >> 10)*4;
  3714. + X86PageEntry table;
  3715. + table.load=phys_readd(table_addr);
  3716. + if (table.block.p) {
  3717. + X86PageEntry entry;
  3718. + Bitu entry_addr=(table.block.base<<12)+(i & 0x3ff)*4;
  3719. + entry.load=phys_readd(entry_addr);
  3720. + if (entry.block.p) {
  3721. + sprintf(out1,"page %05Xxxx -> %04Xxxx flags [uw] %x:%x::%x:%x [d=%x|a=%x]",
  3722. + i,entry.block.base,entry.block.us,table.block.us,
  3723. + entry.block.wr,table.block.wr,entry.block.d,entry.block.a);
  3724. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3725. + }
  3726. + }
  3727. + }
  3728. + } else {
  3729. + Bitu table_addr=(paging.base.page<<12)+(sel >> 10)*4;
  3730. + X86PageEntry table;
  3731. + table.load=phys_readd(table_addr);
  3732. + if (table.block.p) {
  3733. + X86PageEntry entry;
  3734. + Bitu entry_addr=(table.block.base<<12)+(sel & 0x3ff)*4;
  3735. + entry.load=phys_readd(entry_addr);
  3736. + sprintf(out1,"page %05Xxxx -> %04Xxxx flags [puw] %x:%x::%x:%x::%x:%x",sel,entry.block.base,entry.block.p,table.block.p,entry.block.us,table.block.us,entry.block.wr,table.block.wr);
  3737. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3738. + } else {
  3739. + sprintf(out1,"pagetable %03X not present, flags [puw] %x::%x::%x",(sel >> 10),table.block.p,table.block.us,table.block.wr);
  3740. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3741. + }
  3742. + }
  3743. + }
  3744. +};
  3745. +
  3746. +void DEBUG_LogCPUInfo(void) {
  3747. + char out1[512];
  3748. + sprintf(out1,"cr0:%08X cr2:%08X cr3:%08X cpl=%x",cpu.cr0,paging.cr2,paging.cr3,cpu.cpl);
  3749. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3750. + sprintf(out1,"eflags:%08X [vm=%x iopl=%x nt=%x]",reg_flags,GETFLAG(VM)>>17,GETFLAG(IOPL)>>12,GETFLAG(NT)>>14);
  3751. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3752. + sprintf(out1,"GDT base=%08X limit=%08X",cpu.gdt.GetBase(),cpu.gdt.GetLimit());
  3753. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3754. + sprintf(out1,"IDT base=%08X limit=%08X",cpu.idt.GetBase(),cpu.idt.GetLimit());
  3755. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3756. +
  3757. + Bitu sel=CPU_STR();
  3758. + Descriptor desc;
  3759. + if (cpu.gdt.GetDescriptor(sel,desc)) {
  3760. + sprintf(out1,"TR selector=%04X, base=%08X limit=%08X*%X",sel,desc.GetBase(),desc.GetLimit(),desc.saved.seg.g?0x4000:1);
  3761. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3762. + }
  3763. + sel=CPU_SLDT();
  3764. + if (cpu.gdt.GetDescriptor(sel,desc)) {
  3765. + sprintf(out1,"LDT selector=%04X, base=%08X limit=%08X*%X",sel,desc.GetBase(),desc.GetLimit(),desc.saved.seg.g?0x4000:1);
  3766. + LOG(LOG_MISC,LOG_ERROR)(out1);
  3767. + }
  3768. +};
  3769. +
  3770. +_LogGroup loggrp[LOG_MAX]={{"",true},{0,false}};
  3771. +FILE* debuglog;
  3772. +
  3773. +void LOG::operator() (char const* format, ...){
  3774. + char buf[512];
  3775. + va_list msg;
  3776. + va_start(msg,format);
  3777. + vsprintf(buf,format,msg);
  3778. + va_end(msg);
  3779. +
  3780. + if (d_type>=LOG_MAX) return;
  3781. + if ((d_severity!=LOG_ERROR) && (!loggrp[d_type].enabled)) return;
  3782. + DEBUG_ShowMsg("%10u: %s:%s\n",DEBUG_cycle_count,loggrp[d_type].front,buf);
  3783. +}
  3784. +
  3785. +static void LOG_Destroy(Section*) {
  3786. + if(debuglog) fclose(debuglog);
  3787. +}
  3788. +
  3789. +static void LOG_Init(Section * sec) {
  3790. + Section_prop * sect=static_cast<Section_prop *>(sec);
  3791. + const char * blah=sect->Get_string("logfile");
  3792. + if(blah && blah[0] &&(debuglog = fopen(blah,"wt+"))){
  3793. + }else{
  3794. + debuglog=0;
  3795. + }
  3796. + sect->AddDestroyFunction(&LOG_Destroy);
  3797. + char buf[1024];
  3798. + for (Bitu i=1;i<LOG_MAX;i++) {
  3799. + strcpy(buf,loggrp[i].front);
  3800. + buf[strlen(buf)]=0;
  3801. + lowcase(buf);
  3802. + loggrp[i].enabled=sect->Get_bool(buf);
  3803. + }
  3804. +}
  3805. +
  3806. +
  3807. +void LOG_StartUp(void) {
  3808. + /* Setup logging groups */
  3809. + loggrp[LOG_ALL].front="ALL";
  3810. + loggrp[LOG_VGA].front="VGA";
  3811. + loggrp[LOG_VGAGFX].front="VGAGFX";
  3812. + loggrp[LOG_VGAMISC].front="VGAMISC";
  3813. + loggrp[LOG_INT10].front="INT10";
  3814. + loggrp[LOG_SB].front="SBLASTER";
  3815. + loggrp[LOG_DMACONTROL].front="DMA_CONTROL";
  3816. +
  3817. + loggrp[LOG_FPU].front="FPU";
  3818. + loggrp[LOG_CPU].front="CPU";
  3819. + loggrp[LOG_PAGING].front="PAGING";
  3820. +
  3821. + loggrp[LOG_FCB].front="FCB";
  3822. + loggrp[LOG_FILES].front="FILES";
  3823. + loggrp[LOG_IOCTL].front="IOCTL";
  3824. + loggrp[LOG_EXEC].front="EXEC";
  3825. + loggrp[LOG_DOSMISC].front="DOSMISC";
  3826. +
  3827. + loggrp[LOG_PIT].front="PIT";
  3828. + loggrp[LOG_KEYBOARD].front="KEYBOARD";
  3829. + loggrp[LOG_PIC].front="PIC";
  3830. +
  3831. + loggrp[LOG_MOUSE].front="MOUSE";
  3832. + loggrp[LOG_BIOS].front="BIOS";
  3833. + loggrp[LOG_GUI].front="GUI";
  3834. + loggrp[LOG_MISC].front="MISC";
  3835. +
  3836. + loggrp[LOG_IO].front="IO";
  3837. + loggrp[LOG_PCI].front="PCI";
  3838. +
  3839. + /* Register the log section */
  3840. + Section_prop * sect=control->AddSection_prop("log",LOG_Init);
  3841. + Prop_string* Pstring = sect->Add_string("logfile",Property::Changeable::Always,"");
  3842. + Pstring->Set_help("file where the log messages will be saved to");
  3843. + char buf[1024];
  3844. + for (Bitu i=1;i<LOG_MAX;i++) {
  3845. + strcpy(buf,loggrp[i].front);
  3846. + lowcase(buf);
  3847. + Prop_bool* Pbool = sect->Add_bool(buf,Property::Changeable::Always,true);
  3848. + Pbool->Set_help("Enable/Disable logging of this type.");
  3849. + }
  3850. +// MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n");
  3851. +}
  3852. +
  3853. +#if C_HEAVY_DEBUG || C_GDBSERVER
  3854. +void DEBUG_LogInstruction(Bit16u segValue, Bit32u eipValue, ofstream& out) {
  3855. + static char empty[23] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 };
  3856. +
  3857. + PhysPt start = DEBUG_GetAddress(segValue,eipValue);
  3858. + char dline[200];Bitu size;
  3859. + size = DasmI386(dline, start, reg_eip, cpu.code.big);
  3860. + char* res = empty;
  3861. + if (DEBUG_showExtend && (DEBUG_cpuLogType > 0) ) {
  3862. + res = DEBUG_AnalyzeInstruction(dline,false);
  3863. + if (!res || !(*res)) res = empty;
  3864. + Bitu reslen = strlen(res);
  3865. + if (reslen<22) for (Bitu i=0; i<22-reslen; i++) res[reslen+i] = ' '; res[22] = 0;
  3866. + };
  3867. + Bitu len = strlen(dline);
  3868. + if (len<30) for (Bitu i=0; i<30-len; i++) dline[len + i] = ' '; dline[30] = 0;
  3869. +
  3870. + // Get register values
  3871. +
  3872. + if(DEBUG_cpuLogType == 0) {
  3873. + out << setw(4) << SegValue(cs) << ":" << setw(4) << reg_eip << " " << dline;
  3874. + } else if (DEBUG_cpuLogType == 1) {
  3875. + out << setw(4) << SegValue(cs) << ":" << setw(8) << reg_eip << " " << dline << " " << res;
  3876. + } else if (DEBUG_cpuLogType == 2) {
  3877. + char ibytes[200]=""; char tmpc[200];
  3878. + for (Bitu i=0; i<size; i++) {
  3879. + Bit8u value;
  3880. + if (mem_readb_checked(start+i,&value)) sprintf(tmpc,"%s","?? ");
  3881. + else sprintf(tmpc,"%02X ",value);
  3882. + strcat(ibytes,tmpc);
  3883. + }
  3884. + len = strlen(ibytes);
  3885. + if (len<21) { for (Bitu i=0; i<21-len; i++) ibytes[len + i] =' '; ibytes[21]=0;} //NOTE THE BRACKETS
  3886. + out << setw(4) << SegValue(cs) << ":" << setw(8) << reg_eip << " " << dline << " " << res << " " << ibytes;
  3887. + }
  3888. +
  3889. + out << " EAX:" << setw(8) << reg_eax << " EBX:" << setw(8) << reg_ebx
  3890. + << " ECX:" << setw(8) << reg_ecx << " EDX:" << setw(8) << reg_edx
  3891. + << " ESI:" << setw(8) << reg_esi << " EDI:" << setw(8) << reg_edi
  3892. + << " EBP:" << setw(8) << reg_ebp << " ESP:" << setw(8) << reg_esp
  3893. + << " DS:" << setw(4) << SegValue(ds)<< " ES:" << setw(4) << SegValue(es);
  3894. +
  3895. + if(DEBUG_cpuLogType == 0) {
  3896. + out << " SS:" << setw(4) << SegValue(ss) << " C" << (get_CF()>0) << " Z" << (get_ZF()>0)
  3897. + << " S" << (get_SF()>0) << " O" << (get_OF()>0) << " I" << GETFLAGBOOL(IF);
  3898. + } else {
  3899. + out << " FS:" << setw(4) << SegValue(fs) << " GS:" << setw(4) << SegValue(gs)
  3900. + << " SS:" << setw(4) << SegValue(ss)
  3901. + << " CF:" << (get_CF()>0) << " ZF:" << (get_ZF()>0) << " SF:" << (get_SF()>0)
  3902. + << " OF:" << (get_OF()>0) << " AF:" << (get_AF()>0) << " PF:" << (get_PF()>0)
  3903. + << " IF:" << GETFLAGBOOL(IF);
  3904. + }
  3905. + if(DEBUG_cpuLogType == 2) {
  3906. + out << " TF:" << GETFLAGBOOL(TF) << " VM:" << GETFLAGBOOL(VM) <<" FLG:" << setw(8) << reg_flags
  3907. + << " CR0:" << setw(8) << cpu.cr0;
  3908. + }
  3909. + out << endl;
  3910. +};
  3911. +
  3912. +const Bit32u LOGCPUMAX = 20000;
  3913. +
  3914. +static Bit32u logCount = 0;
  3915. +
  3916. +struct TLogInst {
  3917. + Bit16u s_cs;
  3918. + Bit32u eip;
  3919. + Bit32u eax;
  3920. + Bit32u ebx;
  3921. + Bit32u ecx;
  3922. + Bit32u edx;
  3923. + Bit32u esi;
  3924. + Bit32u edi;
  3925. + Bit32u ebp;
  3926. + Bit32u esp;
  3927. + Bit16u s_ds;
  3928. + Bit16u s_es;
  3929. + Bit16u s_fs;
  3930. + Bit16u s_gs;
  3931. + Bit16u s_ss;
  3932. + bool c;
  3933. + bool z;
  3934. + bool s;
  3935. + bool o;
  3936. + bool a;
  3937. + bool p;
  3938. + bool i;
  3939. + char dline[31];
  3940. + char res[23];
  3941. +};
  3942. +
  3943. +TLogInst logInst[LOGCPUMAX];
  3944. +
  3945. +void DEBUG_HeavyLogInstruction(void) {
  3946. +
  3947. + static char empty[23] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 };
  3948. +
  3949. + PhysPt start = DEBUG_GetAddress(SegValue(cs),reg_eip);
  3950. + char dline[200];
  3951. + DasmI386(dline, start, reg_eip, cpu.code.big);
  3952. + char* res = empty;
  3953. + if (DEBUG_showExtend) {
  3954. + res = DEBUG_AnalyzeInstruction(dline,false);
  3955. + if (!res || !(*res)) res = empty;
  3956. + Bitu reslen = strlen(res);
  3957. + if (reslen<22) for (Bitu i=0; i<22-reslen; i++) res[reslen+i] = ' '; res[22] = 0;
  3958. + };
  3959. +
  3960. + Bitu len = strlen(dline);
  3961. + if (len < 30) for (Bitu i=0; i < 30-len; i++) dline[len+i] = ' ';
  3962. + dline[30] = 0;
  3963. +
  3964. + TLogInst & inst = logInst[logCount];
  3965. + strcpy(inst.dline,dline);
  3966. + inst.s_cs = SegValue(cs);
  3967. + inst.eip = reg_eip;
  3968. + strcpy(inst.res,res);
  3969. + inst.eax = reg_eax;
  3970. + inst.ebx = reg_ebx;
  3971. + inst.ecx = reg_ecx;
  3972. + inst.edx = reg_edx;
  3973. + inst.esi = reg_esi;
  3974. + inst.edi = reg_edi;
  3975. + inst.ebp = reg_ebp;
  3976. + inst.esp = reg_esp;
  3977. + inst.s_ds = SegValue(ds);
  3978. + inst.s_es = SegValue(es);
  3979. + inst.s_fs = SegValue(fs);
  3980. + inst.s_gs = SegValue(gs);
  3981. + inst.s_ss = SegValue(ss);
  3982. + inst.c = get_CF()>0;
  3983. + inst.z = get_ZF()>0;
  3984. + inst.s = get_SF()>0;
  3985. + inst.o = get_OF()>0;
  3986. + inst.a = get_AF()>0;
  3987. + inst.p = get_PF()>0;
  3988. + inst.i = GETFLAGBOOL(IF);
  3989. +
  3990. + if (++logCount >= LOGCPUMAX) logCount = 0;
  3991. +};
  3992. +
  3993. +void DEBUG_HeavyWriteLogInstruction(void) {
  3994. + if (!DEBUG_logHeavy) return;
  3995. + DEBUG_logHeavy = false;
  3996. +
  3997. + DEBUG_ShowMsg("DEBUG: Creating cpu log LOGCPU_INT_CD.TXT\n");
  3998. +
  3999. + ofstream out("LOGCPU_INT_CD.TXT");
  4000. + if (!out.is_open()) {
  4001. + DEBUG_ShowMsg("DEBUG: Failed.\n");
  4002. + return;
  4003. + }
  4004. + out << hex << noshowbase << setfill('0') << uppercase;
  4005. + Bit32u startLog = logCount;
  4006. + do {
  4007. + // Write Intructions
  4008. + TLogInst & inst = logInst[startLog];
  4009. + out << setw(4) << inst.s_cs << ":" << setw(8) << inst.eip << " "
  4010. + << inst.dline << " " << inst.res << " EAX:" << setw(8)<< inst.eax
  4011. + << " EBX:" << setw(8) << inst.ebx << " ECX:" << setw(8) << inst.ecx
  4012. + << " EDX:" << setw(8) << inst.edx << " ESI:" << setw(8) << inst.esi
  4013. + << " EDI:" << setw(8) << inst.edi << " EBP:" << setw(8) << inst.ebp
  4014. + << " ESP:" << setw(8) << inst.esp << " DS:" << setw(4) << inst.s_ds
  4015. + << " ES:" << setw(4) << inst.s_es<< " FS:" << setw(4) << inst.s_fs
  4016. + << " GS:" << setw(4) << inst.s_gs<< " SS:" << setw(4) << inst.s_ss
  4017. + << " CF:" << inst.c << " ZF:" << inst.z << " SF:" << inst.s
  4018. + << " OF:" << inst.o << " AF:" << inst.a << " PF:" << inst.p
  4019. + << " IF:" << inst.i << endl;
  4020. +
  4021. +/* fprintf(f,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X IF:%01X\n",
  4022. + logInst[startLog].s_cs,logInst[startLog].eip,logInst[startLog].dline,logInst[startLog].res,logInst[startLog].eax,logInst[startLog].ebx,logInst[startLog].ecx,logInst[startLog].edx,logInst[startLog].esi,logInst[startLog].edi,logInst[startLog].ebp,logInst[startLog].esp,
  4023. + logInst[startLog].s_ds,logInst[startLog].s_es,logInst[startLog].s_fs,logInst[startLog].s_gs,logInst[startLog].s_ss,
  4024. + logInst[startLog].c,logInst[startLog].z,logInst[startLog].s,logInst[startLog].o,logInst[startLog].a,logInst[startLog].p,logInst[startLog].i);*/
  4025. + if (++startLog >= LOGCPUMAX) startLog = 0;
  4026. + } while (startLog != logCount);
  4027. +
  4028. + out.close();
  4029. + DEBUG_ShowMsg("DEBUG: Done.\n");
  4030. +};
  4031. +
  4032. +#endif
  4033. +
  4034. +#endif
  4035. Index: src/debug/Makefile.am
  4036. ===================================================================
  4037. --- src/debug/Makefile.am (revision 3761)
  4038. +++ src/debug/Makefile.am (working copy)
  4039. @@ -1,4 +1,5 @@
  4040. AM_CPPFLAGS = -I$(top_srcdir)/include
  4041.  
  4042. noinst_LIBRARIES = libdebug.a
  4043. -libdebug_a_SOURCES = debug.cpp debug_gui.cpp debug_disasm.cpp debug_inc.h disasm_tables.h debug_win32.cpp
  4044. \ No newline at end of file
  4045. +libdebug_a_SOURCES = debug.cpp debug_gui.cpp debug_disasm.cpp debug_inc.h \
  4046. + disasm_tables.h debug_win32.cpp debug_log.cpp debug_helpers.cpp gdb_server.cpp poll.cpp poll.h
  4047. Index: src/debug/debug_helpers.cpp
  4048. ===================================================================
  4049. --- src/debug/debug_helpers.cpp (revision 0)
  4050. +++ src/debug/debug_helpers.cpp (revision 0)
  4051. @@ -0,0 +1,347 @@
  4052. +/*
  4053. + * Copyright (C) 2002-2011 The DOSBox Team
  4054. + *
  4055. + * This program is free software; you can redistribute it and/or modify
  4056. + * it under the terms of the GNU General Public License as published by
  4057. + * the Free Software Foundation; either version 2 of the License, or
  4058. + * (at your option) any later version.
  4059. + *
  4060. + * This program is distributed in the hope that it will be useful,
  4061. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4062. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4063. + * GNU General Public License for more details.
  4064. + *
  4065. + * You should have received a copy of the GNU General Public License
  4066. + * along with this program; if not, write to the Free Software
  4067. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  4068. + */
  4069. +
  4070. +#include "dosbox.h"
  4071. +#if C_DEBUG || C_GDBSERVER
  4072. +
  4073. +#include <string.h>
  4074. +#include <list>
  4075. +#include <ctype.h>
  4076. +#include <fstream>
  4077. +#include <iomanip>
  4078. +#include <string>
  4079. +#include <sstream>
  4080. +using namespace std;
  4081. +
  4082. +#include "debug.h"
  4083. +#include "cross.h" //snprintf
  4084. +#include "cpu.h"
  4085. +#include "video.h"
  4086. +#include "pic.h"
  4087. +#include "mapper.h"
  4088. +#include "cpu.h"
  4089. +#include "callback.h"
  4090. +#include "inout.h"
  4091. +#include "mixer.h"
  4092. +#include "timer.h"
  4093. +#include "paging.h"
  4094. +#include "support.h"
  4095. +#include "shell.h"
  4096. +#include "programs.h"
  4097. +#include "debug_inc.h"
  4098. +#include "../cpu/lazyflags.h"
  4099. +#include "keyboard.h"
  4100. +#include "setup.h"
  4101. +
  4102. +bool DEBUG_exitLoop = false;
  4103. +Bit16u DEBUG_dataSeg;
  4104. +Bit32u DEBUG_dataOfs;
  4105. +char DEBUG_curSelectorName[3] = { 0,0,0 };
  4106. +
  4107. +Bit32u PhysMakeProt(Bit16u selector, Bit32u offset)
  4108. +{
  4109. + Descriptor desc;
  4110. + if (cpu.gdt.GetDescriptor(selector,desc)) return desc.GetBase()+offset;
  4111. + return 0;
  4112. +};
  4113. +
  4114. +Bit32u DEBUG_GetAddress(Bit16u seg, Bit32u offset)
  4115. +{
  4116. + if (seg==SegValue(cs)) return SegPhys(cs)+offset;
  4117. + if (cpu.pmode && !(reg_flags & FLAG_VM)) {
  4118. + Descriptor desc;
  4119. + if (cpu.gdt.GetDescriptor(seg,desc)) return PhysMakeProt(seg,offset);
  4120. + }
  4121. + return (seg<<4)+offset;
  4122. +}
  4123. +
  4124. +static char empty_sel[] = { ' ',' ',0 };
  4125. +
  4126. +Bit32u DEBUG_GetHexValue(char* str, char*& hex)
  4127. +{
  4128. + Bit32u value = 0;
  4129. + Bit32u regval = 0;
  4130. + hex = str;
  4131. + while (*hex==' ') hex++;
  4132. + if (strstr(hex,"EAX")==hex) { hex+=3; regval = reg_eax; };
  4133. + if (strstr(hex,"EBX")==hex) { hex+=3; regval = reg_ebx; };
  4134. + if (strstr(hex,"ECX")==hex) { hex+=3; regval = reg_ecx; };
  4135. + if (strstr(hex,"EDX")==hex) { hex+=3; regval = reg_edx; };
  4136. + if (strstr(hex,"ESI")==hex) { hex+=3; regval = reg_esi; };
  4137. + if (strstr(hex,"EDI")==hex) { hex+=3; regval = reg_edi; };
  4138. + if (strstr(hex,"EBP")==hex) { hex+=3; regval = reg_ebp; };
  4139. + if (strstr(hex,"ESP")==hex) { hex+=3; regval = reg_esp; };
  4140. + if (strstr(hex,"EIP")==hex) { hex+=3; regval = reg_eip; };
  4141. + if (strstr(hex,"AX")==hex) { hex+=2; regval = reg_ax; };
  4142. + if (strstr(hex,"BX")==hex) { hex+=2; regval = reg_bx; };
  4143. + if (strstr(hex,"CX")==hex) { hex+=2; regval = reg_cx; };
  4144. + if (strstr(hex,"DX")==hex) { hex+=2; regval = reg_dx; };
  4145. + if (strstr(hex,"SI")==hex) { hex+=2; regval = reg_si; };
  4146. + if (strstr(hex,"DI")==hex) { hex+=2; regval = reg_di; };
  4147. + if (strstr(hex,"BP")==hex) { hex+=2; regval = reg_bp; };
  4148. + if (strstr(hex,"SP")==hex) { hex+=2; regval = reg_sp; };
  4149. + if (strstr(hex,"IP")==hex) { hex+=2; regval = reg_ip; };
  4150. + if (strstr(hex,"CS")==hex) { hex+=2; regval = SegValue(cs); };
  4151. + if (strstr(hex,"DS")==hex) { hex+=2; regval = SegValue(ds); };
  4152. + if (strstr(hex,"ES")==hex) { hex+=2; regval = SegValue(es); };
  4153. + if (strstr(hex,"FS")==hex) { hex+=2; regval = SegValue(fs); };
  4154. + if (strstr(hex,"GS")==hex) { hex+=2; regval = SegValue(gs); };
  4155. + if (strstr(hex,"SS")==hex) { hex+=2; regval = SegValue(ss); };
  4156. +
  4157. + while (*hex) {
  4158. + if ((*hex>='0') && (*hex<='9')) value = (value<<4)+*hex-'0';
  4159. + else if ((*hex>='A') && (*hex<='F')) value = (value<<4)+*hex-'A'+10;
  4160. + else {
  4161. + if(*hex == '+') {hex++;return regval + value + DEBUG_GetHexValue(hex,hex); };
  4162. + if(*hex == '-') {hex++;return regval + value - DEBUG_GetHexValue(hex,hex); };
  4163. + break; // No valid char
  4164. + }
  4165. + hex++;
  4166. + };
  4167. + return regval + value;
  4168. +}
  4169. +
  4170. +bool DEBUG_GetDescriptorInfo(char* selname, char* out1, char* out2)
  4171. +{
  4172. + Bitu sel;
  4173. + Descriptor desc;
  4174. +
  4175. + if (strstr(selname,"cs") || strstr(selname,"CS")) sel = SegValue(cs);
  4176. + else if (strstr(selname,"ds") || strstr(selname,"DS")) sel = SegValue(ds);
  4177. + else if (strstr(selname,"es") || strstr(selname,"ES")) sel = SegValue(es);
  4178. + else if (strstr(selname,"fs") || strstr(selname,"FS")) sel = SegValue(fs);
  4179. + else if (strstr(selname,"gs") || strstr(selname,"GS")) sel = SegValue(gs);
  4180. + else if (strstr(selname,"ss") || strstr(selname,"SS")) sel = SegValue(ss);
  4181. + else {
  4182. + sel = DEBUG_GetHexValue(selname,selname);
  4183. + if (*selname==0) selname=empty_sel;
  4184. + }
  4185. + if (cpu.gdt.GetDescriptor(sel,desc)) {
  4186. + switch (desc.Type()) {
  4187. + case DESC_TASK_GATE:
  4188. + sprintf(out1,"%s: s:%08X type:%02X p",selname,desc.GetSelector(),desc.saved.gate.type);
  4189. + sprintf(out2," TaskGate dpl : %01X %1X",desc.saved.gate.dpl,desc.saved.gate.p);
  4190. + return true;
  4191. + case DESC_LDT:
  4192. + case DESC_286_TSS_A:
  4193. + case DESC_286_TSS_B:
  4194. + case DESC_386_TSS_A:
  4195. + case DESC_386_TSS_B:
  4196. + sprintf(out1,"%s: b:%08X type:%02X pag",selname,desc.GetBase(),desc.saved.seg.type);
  4197. + sprintf(out2," l:%08X dpl : %01X %1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.g);
  4198. + return true;
  4199. + case DESC_286_CALL_GATE:
  4200. + case DESC_386_CALL_GATE:
  4201. + sprintf(out1,"%s: s:%08X type:%02X p params: %02X",selname,desc.GetSelector(),desc.saved.gate.type,desc.saved.gate.paramcount);
  4202. + sprintf(out2," o:%08X dpl : %01X %1X",desc.GetOffset(),desc.saved.gate.dpl,desc.saved.gate.p);
  4203. + return true;
  4204. + case DESC_286_INT_GATE:
  4205. + case DESC_286_TRAP_GATE:
  4206. + case DESC_386_INT_GATE:
  4207. + case DESC_386_TRAP_GATE:
  4208. + sprintf(out1,"%s: s:%08X type:%02X p",selname,desc.GetSelector(),desc.saved.gate.type);
  4209. + sprintf(out2," o:%08X dpl : %01X %1X",desc.GetOffset(),desc.saved.gate.dpl,desc.saved.gate.p);
  4210. + return true;
  4211. + }
  4212. + sprintf(out1,"%s: b:%08X type:%02X parbg",selname,desc.GetBase(),desc.saved.seg.type);
  4213. + sprintf(out2," l:%08X dpl : %01X %1X%1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.big,desc.saved.seg.g);
  4214. + return true;
  4215. + } else {
  4216. + strcpy(out1," ");
  4217. + strcpy(out2," ");
  4218. + }
  4219. + return false;
  4220. +};
  4221. +
  4222. +char* DEBUG_AnalyzeInstruction(char* inst, bool saveSelector) {
  4223. + static char result[256];
  4224. +
  4225. + char instu[256];
  4226. + char prefix[3];
  4227. + Bit16u seg;
  4228. +
  4229. + strcpy(instu,inst);
  4230. + upcase(instu);
  4231. +
  4232. + result[0] = 0;
  4233. + char* pos = strchr(instu,'[');
  4234. + if (pos) {
  4235. + // Segment prefix ?
  4236. + if (*(pos-1)==':') {
  4237. + char* segpos = pos-3;
  4238. + prefix[0] = tolower(*segpos);
  4239. + prefix[1] = tolower(*(segpos+1));
  4240. + prefix[2] = 0;
  4241. + seg = (Bit16u)DEBUG_GetHexValue(segpos,segpos);
  4242. + } else {
  4243. + if (strstr(pos,"SP") || strstr(pos,"BP")) {
  4244. + seg = SegValue(ss);
  4245. + strcpy(prefix,"ss");
  4246. + } else {
  4247. + seg = SegValue(ds);
  4248. + strcpy(prefix,"ds");
  4249. + };
  4250. + };
  4251. +
  4252. + pos++;
  4253. + Bit32u adr = DEBUG_GetHexValue(pos,pos);
  4254. + while (*pos!=']') {
  4255. + if (*pos=='+') {
  4256. + pos++;
  4257. + adr += DEBUG_GetHexValue(pos,pos);
  4258. + } else if (*pos=='-') {
  4259. + pos++;
  4260. + adr -= DEBUG_GetHexValue(pos,pos);
  4261. + } else
  4262. + pos++;
  4263. + };
  4264. + Bit32u address = DEBUG_GetAddress(seg,adr);
  4265. + if (!(get_tlb_readhandler(address)->flags & PFLAG_INIT)) {
  4266. + static char outmask[] = "%s:[%04X]=%02X";
  4267. +
  4268. + if (cpu.pmode) outmask[6] = '8';
  4269. + switch (DasmLastOperandSize()) {
  4270. + case 8 : { Bit8u val = mem_readb(address);
  4271. + outmask[12] = '2';
  4272. + sprintf(result,outmask,prefix,adr,val);
  4273. + } break;
  4274. + case 16: { Bit16u val = mem_readw(address);
  4275. + outmask[12] = '4';
  4276. + sprintf(result,outmask,prefix,adr,val);
  4277. + } break;
  4278. + case 32: { Bit32u val = mem_readd(address);
  4279. + outmask[12] = '8';
  4280. + sprintf(result,outmask,prefix,adr,val);
  4281. + } break;
  4282. + }
  4283. + } else {
  4284. + sprintf(result,"[illegal]");
  4285. + }
  4286. +#ifndef C_GDBSERVER
  4287. + // Variable found ?
  4288. + CDebugVar* var = CDebugVar::FindVar(address);
  4289. + if (var) {
  4290. + // Replace occurance
  4291. + char* pos1 = strchr(inst,'[');
  4292. + char* pos2 = strchr(inst,']');
  4293. + if (pos1 && pos2) {
  4294. + char temp[256];
  4295. + strcpy(temp,pos2); // save end
  4296. + pos1++; *pos1 = 0; // cut after '['
  4297. + strcat(inst,var->GetName()); // add var name
  4298. + strcat(inst,temp); // add end
  4299. + };
  4300. + };
  4301. +#endif
  4302. + // show descriptor info, if available
  4303. + if ((cpu.pmode) && saveSelector) {
  4304. + strcpy(DEBUG_curSelectorName,prefix);
  4305. + };
  4306. + };
  4307. + // If it is a callback add additional info
  4308. + pos = strstr(inst,"callback");
  4309. + if (pos) {
  4310. + pos += 9;
  4311. + Bitu nr = DEBUG_GetHexValue(pos,pos);
  4312. + const char* descr = CALLBACK_GetDescription(nr);
  4313. + if (descr) {
  4314. + strcat(inst," ("); strcat(inst,descr); strcat(inst,")");
  4315. + }
  4316. + };
  4317. + // Must be a jump
  4318. + if (instu[0] == 'J')
  4319. + {
  4320. + bool jmp = false;
  4321. + switch (instu[1]) {
  4322. + case 'A' : { jmp = (get_CF()?false:true) && (get_ZF()?false:true); // JA
  4323. + } break;
  4324. + case 'B' : { if (instu[2] == 'E') {
  4325. + jmp = (get_CF()?true:false) || (get_ZF()?true:false); // JBE
  4326. + } else {
  4327. + jmp = get_CF()?true:false; // JB
  4328. + }
  4329. + } break;
  4330. + case 'C' : { if (instu[2] == 'X') {
  4331. + jmp = reg_cx == 0; // JCXZ
  4332. + } else {
  4333. + jmp = get_CF()?true:false; // JC
  4334. + }
  4335. + } break;
  4336. + case 'E' : { jmp = get_ZF()?true:false; // JE
  4337. + } break;
  4338. + case 'G' : { if (instu[2] == 'E') {
  4339. + jmp = (get_SF()?true:false)==(get_OF()?true:false); // JGE
  4340. + } else {
  4341. + jmp = (get_ZF()?false:true) && ((get_SF()?true:false)==(get_OF()?true:false)); // JG
  4342. + }
  4343. + } break;
  4344. + case 'L' : { if (instu[2] == 'E') {
  4345. + jmp = (get_ZF()?true:false) || ((get_SF()?true:false)!=(get_OF()?true:false)); // JLE
  4346. + } else {
  4347. + jmp = (get_SF()?true:false)!=(get_OF()?true:false); // JL
  4348. + }
  4349. + } break;
  4350. + case 'M' : { jmp = true; // JMP
  4351. + } break;
  4352. + case 'N' : { switch (instu[2]) {
  4353. + case 'B' :
  4354. + case 'C' : { jmp = get_CF()?false:true; // JNB / JNC
  4355. + } break;
  4356. + case 'E' : { jmp = get_ZF()?false:true; // JNE
  4357. + } break;
  4358. + case 'O' : { jmp = get_OF()?false:true; // JNO
  4359. + } break;
  4360. + case 'P' : { jmp = get_PF()?false:true; // JNP
  4361. + } break;
  4362. + case 'S' : { jmp = get_SF()?false:true; // JNS
  4363. + } break;
  4364. + case 'Z' : { jmp = get_ZF()?false:true; // JNZ
  4365. + } break;
  4366. + }
  4367. + } break;
  4368. + case 'O' : { jmp = get_OF()?true:false; // JO
  4369. + } break;
  4370. + case 'P' : { if (instu[2] == 'O') {
  4371. + jmp = get_PF()?false:true; // JPO
  4372. + } else {
  4373. + jmp = get_SF()?true:false; // JP / JPE
  4374. + }
  4375. + } break;
  4376. + case 'S' : { jmp = get_SF()?true:false; // JS
  4377. + } break;
  4378. + case 'Z' : { jmp = get_ZF()?true:false; // JZ
  4379. + } break;
  4380. + }
  4381. + if (jmp) {
  4382. + pos = strchr(instu,'$');
  4383. + if (pos) {
  4384. + pos = strchr(instu,'+');
  4385. + if (pos) {
  4386. + strcpy(result,"(down)");
  4387. + } else {
  4388. + strcpy(result,"(up)");
  4389. + }
  4390. + }
  4391. + } else {
  4392. + sprintf(result,"(no jmp)");
  4393. + }
  4394. + }
  4395. + return result;
  4396. +};
  4397. +
  4398. +#endif
  4399. Index: src/debug/debug_gui.cpp
  4400. ===================================================================
  4401. --- src/debug/debug_gui.cpp (revision 3761)
  4402. +++ src/debug/debug_gui.cpp (working copy)
  4403. @@ -32,10 +32,6 @@
  4404. #include "debug.h"
  4405. #include "debug_inc.h"
  4406.  
  4407. -struct _LogGroup {
  4408. - char const* front;
  4409. - bool enabled;
  4410. -};
  4411. #include <list>
  4412. #include <string>
  4413. using namespace std;
  4414. @@ -45,12 +41,10 @@
  4415. static list<string>::iterator logBuffPos = logBuff.end();
  4416.  
  4417. static _LogGroup loggrp[LOG_MAX]={{"",true},{0,false}};
  4418. -static FILE* debuglog;
  4419. +extern FILE* debuglog;
  4420.  
  4421. extern int old_cursor_state;
  4422.  
  4423. -
  4424. -
  4425. void DEBUG_ShowMsg(char const* format,...) {
  4426.  
  4427. char buf[512];
  4428. @@ -100,19 +94,7 @@
  4429. wrefresh(dbg.win_out);
  4430. }
  4431.  
  4432. -void LOG::operator() (char const* format, ...){
  4433. - char buf[512];
  4434. - va_list msg;
  4435. - va_start(msg,format);
  4436. - vsprintf(buf,format,msg);
  4437. - va_end(msg);
  4438.  
  4439. - if (d_type>=LOG_MAX) return;
  4440. - if ((d_severity!=LOG_ERROR) && (!loggrp[d_type].enabled)) return;
  4441. - DEBUG_ShowMsg("%10u: %s:%s\n",cycle_count,loggrp[d_type].front,buf);
  4442. -}
  4443. -
  4444. -
  4445. static void Draw_RegisterLayout(void) {
  4446. mvwaddstr(dbg.win_reg,0,0,"EAX=");
  4447. mvwaddstr(dbg.win_reg,1,0,"EBX=");
  4448. @@ -193,77 +175,7 @@
  4449. init_pair(PAIR_BLACK_GREY, COLOR_BLACK /*| FOREGROUND_INTENSITY */, COLOR_WHITE);
  4450. init_pair(PAIR_GREY_RED, COLOR_WHITE/*| FOREGROUND_INTENSITY */, COLOR_RED);
  4451. }
  4452. -static void LOG_Destroy(Section*) {
  4453. - if(debuglog) fclose(debuglog);
  4454. -}
  4455.  
  4456. -static void LOG_Init(Section * sec) {
  4457. - Section_prop * sect=static_cast<Section_prop *>(sec);
  4458. - const char * blah=sect->Get_string("logfile");
  4459. - if(blah && blah[0] &&(debuglog = fopen(blah,"wt+"))){
  4460. - }else{
  4461. - debuglog=0;
  4462. - }
  4463. - sect->AddDestroyFunction(&LOG_Destroy);
  4464. - char buf[1024];
  4465. - for (Bitu i=1;i<LOG_MAX;i++) {
  4466. - strcpy(buf,loggrp[i].front);
  4467. - buf[strlen(buf)]=0;
  4468. - lowcase(buf);
  4469. - loggrp[i].enabled=sect->Get_bool(buf);
  4470. - }
  4471. -}
  4472. -
  4473. -
  4474. -void LOG_StartUp(void) {
  4475. - /* Setup logging groups */
  4476. - loggrp[LOG_ALL].front="ALL";
  4477. - loggrp[LOG_VGA].front="VGA";
  4478. - loggrp[LOG_VGAGFX].front="VGAGFX";
  4479. - loggrp[LOG_VGAMISC].front="VGAMISC";
  4480. - loggrp[LOG_INT10].front="INT10";
  4481. - loggrp[LOG_SB].front="SBLASTER";
  4482. - loggrp[LOG_DMACONTROL].front="DMA_CONTROL";
  4483. -
  4484. - loggrp[LOG_FPU].front="FPU";
  4485. - loggrp[LOG_CPU].front="CPU";
  4486. - loggrp[LOG_PAGING].front="PAGING";
  4487. -
  4488. - loggrp[LOG_FCB].front="FCB";
  4489. - loggrp[LOG_FILES].front="FILES";
  4490. - loggrp[LOG_IOCTL].front="IOCTL";
  4491. - loggrp[LOG_EXEC].front="EXEC";
  4492. - loggrp[LOG_DOSMISC].front="DOSMISC";
  4493. -
  4494. - loggrp[LOG_PIT].front="PIT";
  4495. - loggrp[LOG_KEYBOARD].front="KEYBOARD";
  4496. - loggrp[LOG_PIC].front="PIC";
  4497. -
  4498. - loggrp[LOG_MOUSE].front="MOUSE";
  4499. - loggrp[LOG_BIOS].front="BIOS";
  4500. - loggrp[LOG_GUI].front="GUI";
  4501. - loggrp[LOG_MISC].front="MISC";
  4502. -
  4503. - loggrp[LOG_IO].front="IO";
  4504. - loggrp[LOG_PCI].front="PCI";
  4505. -
  4506. - /* Register the log section */
  4507. - Section_prop * sect=control->AddSection_prop("log",LOG_Init);
  4508. - Prop_string* Pstring = sect->Add_string("logfile",Property::Changeable::Always,"");
  4509. - Pstring->Set_help("file where the log messages will be saved to");
  4510. - char buf[1024];
  4511. - for (Bitu i=1;i<LOG_MAX;i++) {
  4512. - strcpy(buf,loggrp[i].front);
  4513. - lowcase(buf);
  4514. - Prop_bool* Pbool = sect->Add_bool(buf,Property::Changeable::Always,true);
  4515. - Pbool->Set_help("Enable/Disable logging of this type.");
  4516. - }
  4517. -// MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n");
  4518. -}
  4519. -
  4520. -
  4521. -
  4522. -
  4523. void DBGUI_StartUp(void) {
  4524. /* Start the main window */
  4525. dbg.win_main=initscr();
  4526. @@ -277,10 +189,11 @@
  4527. #endif
  4528. old_cursor_state = curs_set(0);
  4529. start_color();
  4530. - cycle_count=0;
  4531. + DEBUG_cycle_count=0;
  4532. MakePairs();
  4533. MakeSubWindows();
  4534.  
  4535. }
  4536.  
  4537. #endif
  4538. +
  4539. Index: src/cpu/core_normal.cpp
  4540. ===================================================================
  4541. --- src/cpu/core_normal.cpp (revision 3761)
  4542. +++ src/cpu/core_normal.cpp (working copy)
  4543. @@ -28,7 +28,7 @@
  4544. #include "fpu.h"
  4545. #include "paging.h"
  4546.  
  4547. -#if C_DEBUG
  4548. +#if C_DEBUG || C_GDBSERVER
  4549. #include "debug.h"
  4550. #endif
  4551.  
  4552. @@ -49,7 +49,7 @@
  4553. #define SaveMd(off,val) mem_writed_inline(off,val)
  4554. #endif
  4555.  
  4556. -extern Bitu cycle_count;
  4557. +extern Bitu DEBUG_cycle_count;
  4558.  
  4559. #if C_FPU
  4560. #define CPU_FPU 1 //Enable FPU escape instructions
  4561. @@ -145,14 +145,14 @@
  4562. BaseDS=SegBase(ds);
  4563. BaseSS=SegBase(ss);
  4564. core.base_val_ds=ds;
  4565. -#if C_DEBUG
  4566. -#if C_HEAVY_DEBUG
  4567. +#if C_DEBUG || C_GDBSERVER
  4568. +#if C_HEAVY_DEBUG || C_GDBSERVER
  4569. if (DEBUG_HeavyIsBreakpoint()) {
  4570. FillFlags();
  4571. - return debugCallback;
  4572. + return DEBUG_debugCallback;
  4573. };
  4574. #endif
  4575. - cycle_count++;
  4576. + DEBUG_cycle_count++;
  4577. #endif
  4578. restart_opcode:
  4579. switch (core.opcode_index+Fetchb()) {
  4580. @@ -162,7 +162,7 @@
  4581. #include "core_normal/prefix_66_0f.h"
  4582. default:
  4583. illegal_opcode:
  4584. -#if C_DEBUG
  4585. +#if C_DEBUG
  4586. {
  4587. Bitu len=(GETIP-reg_eip);
  4588. LOADIP;
  4589. Index: src/cpu/core_simple.cpp
  4590. ===================================================================
  4591. --- src/cpu/core_simple.cpp (revision 3761)
  4592. +++ src/cpu/core_simple.cpp (working copy)
  4593. @@ -27,7 +27,7 @@
  4594. #include "pic.h"
  4595. #include "fpu.h"
  4596.  
  4597. -#if C_DEBUG
  4598. +#if C_DEBUG || C_GDBSERVER
  4599. #include "debug.h"
  4600. #endif
  4601.  
  4602. @@ -41,7 +41,7 @@
  4603. #define SaveMw(off,val) mem_writew(off,val)
  4604. #define SaveMd(off,val) mem_writed(off,val)
  4605.  
  4606. -extern Bitu cycle_count;
  4607. +extern Bitu DEBUG_cycle_count;
  4608.  
  4609. #if C_FPU
  4610. #define CPU_FPU 1 //Enable FPU escape instructions
  4611. @@ -141,14 +141,14 @@
  4612. BaseDS=SegBase(ds);
  4613. BaseSS=SegBase(ss);
  4614. core.base_val_ds=ds;
  4615. -#if C_DEBUG
  4616. -#if C_HEAVY_DEBUG
  4617. +#if C_DEBUG || C_GDBSERVER
  4618. +#if C_HEAVY_DEBUG || C_GDBSERVER
  4619. if (DEBUG_HeavyIsBreakpoint()) {
  4620. FillFlags();
  4621. - return debugCallback;
  4622. + return DEBUG_debugCallback;
  4623. };
  4624. #endif
  4625. - cycle_count++;
  4626. + DEBUG_cycle_count++;
  4627. #endif
  4628. restart_opcode:
  4629. switch (core.opcode_index+Fetchb()) {
  4630. @@ -159,7 +159,7 @@
  4631. #include "core_normal/prefix_66_0f.h"
  4632. default:
  4633. illegal_opcode:
  4634. -#if C_DEBUG
  4635. +#if C_DEBUG
  4636. {
  4637. Bitu len=(GETIP-reg_eip);
  4638. LOADIP;
  4639. Index: src/cpu/paging.cpp
  4640. ===================================================================
  4641. --- src/cpu/paging.cpp (revision 3761)
  4642. +++ src/cpu/paging.cpp (working copy)
  4643. @@ -130,7 +130,7 @@
  4644. }
  4645. return 0;
  4646. }
  4647. -#if C_DEBUG
  4648. +#if C_DEBUG || C_GDBSERVER
  4649. Bitu DEBUG_EnableDebugger(void);
  4650. #endif
  4651.  
  4652. @@ -155,7 +155,7 @@
  4653. cpu.mpl=3;
  4654.  
  4655. CPU_Exception(EXCEPTION_PF,faultcode);
  4656. -#if C_DEBUG
  4657. +#if C_DEBUG || C_GDBSERVER
  4658. // DEBUG_EnableDebugger();
  4659. #endif
  4660. DOSBOX_RunMachine();
  4661. Index: src/cpu/core_dyn_x86.cpp
  4662. ===================================================================
  4663. --- src/cpu/core_dyn_x86.cpp (revision 3761)
  4664. +++ src/cpu/core_dyn_x86.cpp (working copy)
  4665. @@ -113,7 +113,7 @@
  4666. BR_Cycles,
  4667. BR_Link1,BR_Link2,
  4668. BR_Opcode,
  4669. -#if (C_DEBUG)
  4670. +#if C_DEBUG || C_GDBSERVER
  4671. BR_OpcodeFull,
  4672. #endif
  4673. BR_Iret,
  4674. @@ -261,8 +261,8 @@
  4675. /* Determine the linear address of CS:EIP */
  4676. restart_core:
  4677. PhysPt ip_point=SegPhys(cs)+reg_eip;
  4678. - #if C_HEAVY_DEBUG
  4679. - if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
  4680. + #if C_HEAVY_DEBUG || C_GDBSERVER
  4681. + if (DEBUG_HeavyIsBreakpoint()) return DEBUG_debugCallback;
  4682. #endif
  4683. CodePageHandler * chandler=0;
  4684. if (GCC_UNLIKELY(MakeCodePage(ip_point,chandler))) {
  4685. @@ -296,10 +296,10 @@
  4686. BlockReturn ret=gen_runcode(block->cache.start);
  4687. switch (ret) {
  4688. case BR_Iret:
  4689. -#if C_HEAVY_DEBUG
  4690. +#if C_HEAVY_DEBUG || C_GDBSERVER
  4691. if (DEBUG_HeavyIsBreakpoint()) {
  4692. if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
  4693. - return debugCallback;
  4694. + return DEBUG_debugCallback;
  4695. }
  4696. #endif
  4697. if (!GETFLAG(TF)) {
  4698. @@ -315,13 +315,13 @@
  4699. return CBRET_NONE;
  4700. case BR_Normal:
  4701. /* Maybe check if we staying in the same page? */
  4702. -#if C_HEAVY_DEBUG
  4703. - if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
  4704. +#if C_HEAVY_DEBUG || C_GDBSERVER
  4705. + if (DEBUG_HeavyIsBreakpoint()) return DEBUG_debugCallback;
  4706. #endif
  4707. goto restart_core;
  4708. case BR_Cycles:
  4709. -#if C_HEAVY_DEBUG
  4710. - if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
  4711. +#if C_HEAVY_DEBUG || C_GDBSERVER
  4712. + if (DEBUG_HeavyIsBreakpoint()) return DEBUG_debugCallback;
  4713. #endif
  4714. if (!dyn_dh_fpu.state_used) return CBRET_NONE;
  4715. DH_FPU_SAVE_REINIT
  4716. @@ -339,7 +339,7 @@
  4717. CPU_Cycles=1;
  4718. if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
  4719. return CPU_Core_Normal_Run();
  4720. -#if (C_DEBUG)
  4721. +#if C_DEBUG || C_GDBSERVER
  4722. case BR_OpcodeFull:
  4723. CPU_CycleLeft+=CPU_Cycles;
  4724. CPU_Cycles=1;
  4725. Index: src/cpu/core_prefetch.cpp
  4726. ===================================================================
  4727. --- src/cpu/core_prefetch.cpp (revision 3761)
  4728. +++ src/cpu/core_prefetch.cpp (working copy)
  4729. @@ -29,7 +29,7 @@
  4730. #include "fpu.h"
  4731. #include "paging.h"
  4732.  
  4733. -#if C_DEBUG
  4734. +#if C_DEBUG || C_GDBSERVER
  4735. #include "debug.h"
  4736. #endif
  4737.  
  4738. @@ -50,7 +50,7 @@
  4739. #define SaveMd(off,val) mem_writed_inline(off,val)
  4740. #endif
  4741.  
  4742. -extern Bitu cycle_count;
  4743. +extern Bitu DEBUG_cycle_count;
  4744.  
  4745. #if C_FPU
  4746. #define CPU_FPU 1 //Enable FPU escape instructions
  4747. @@ -220,14 +220,14 @@
  4748. BaseDS=SegBase(ds);
  4749. BaseSS=SegBase(ss);
  4750. core.base_val_ds=ds;
  4751. -#if C_DEBUG
  4752. -#if C_HEAVY_DEBUG
  4753. +#if C_DEBUG || C_GDBSERVER
  4754. +#if C_HEAVY_DEBUG || C_GDBSERVER
  4755. if (DEBUG_HeavyIsBreakpoint()) {
  4756. FillFlags();
  4757. - return debugCallback;
  4758. + return DEBUG_debugCallback;
  4759. };
  4760. #endif
  4761. - cycle_count++;
  4762. + DEBUG_cycle_count++;
  4763. #endif
  4764. restart_opcode:
  4765. Bit8u next_opcode=Fetchb();
  4766. Index: src/cpu/core_full.cpp
  4767. ===================================================================
  4768. --- src/cpu/core_full.cpp (revision 3761)
  4769. +++ src/cpu/core_full.cpp (working copy)
  4770. @@ -64,12 +64,12 @@
  4771. Bits CPU_Core_Full_Run(void) {
  4772. FullData inst;
  4773. while (CPU_Cycles-->0) {
  4774. -#if C_DEBUG
  4775. - cycle_count++;
  4776. -#if C_HEAVY_DEBUG
  4777. +#if C_DEBUG || C_GDBSERVER
  4778. + DEBUG_cycle_count++;
  4779. +#if C_HEAVY_DEBUG || C_GDBSERVER
  4780. if (DEBUG_HeavyIsBreakpoint()) {
  4781. FillFlags();
  4782. - return debugCallback;
  4783. + return DEBUG_debugCallback;
  4784. };
  4785. #endif
  4786. #endif
  4787. Index: src/cpu/core_normal/prefix_none.h
  4788. ===================================================================
  4789. --- src/cpu/core_normal/prefix_none.h (revision 3761)
  4790. +++ src/cpu/core_normal/prefix_none.h (working copy)
  4791. @@ -741,10 +741,10 @@
  4792. CPU_RET(false,0,GETIP);
  4793. continue;
  4794. CASE_B(0xcc) /* INT3 */
  4795. -#if C_DEBUG
  4796. +#if C_DEBUG || C_GDBSERVER
  4797. FillFlags();
  4798. if (DEBUG_Breakpoint())
  4799. - return debugCallback;
  4800. + return DEBUG_debugCallback;
  4801. #endif
  4802. CPU_SW_Interrupt_NoIOPLCheck(3,GETIP);
  4803. #if CPU_TRAP_CHECK
  4804. @@ -754,10 +754,10 @@
  4805. CASE_B(0xcd) /* INT Ib */
  4806. {
  4807. Bit8u num=Fetchb();
  4808. -#if C_DEBUG
  4809. +#if C_DEBUG || C_GDBSERVER
  4810. FillFlags();
  4811. if (DEBUG_IntBreakpoint(num)) {
  4812. - return debugCallback;
  4813. + return DEBUG_debugCallback;
  4814. }
  4815. #endif
  4816. CPU_SW_Interrupt(num,GETIP);
  4817. Index: src/cpu/core_dyn_x86/decoder.h
  4818. ===================================================================
  4819. --- src/cpu/core_dyn_x86/decoder.h (revision 3761)
  4820. +++ src/cpu/core_dyn_x86/decoder.h (working copy)
  4821. @@ -2697,7 +2697,7 @@
  4822. gen_return(BR_Opcode);
  4823. dyn_closeblock();
  4824. goto finish_block;
  4825. -#if (C_DEBUG)
  4826. +#if C_DEBUG || C_GDBSERVER
  4827. dyn_set_eip_last();
  4828. dyn_reduce_cycles();
  4829. dyn_save_critical_regs();
  4830. Index: src/cpu/cpu.cpp
  4831. ===================================================================
  4832. --- src/cpu/cpu.cpp (revision 3761)
  4833. +++ src/cpu/cpu.cpp (working copy)
  4834. @@ -90,7 +90,7 @@
  4835. * In non-debug mode dosbox doesn't do detection (and hence doesn't crash at
  4836. * that point). (game might crash later due to the unhandled exception) */
  4837.  
  4838. -#if C_DEBUG
  4839. +#if C_DEBUG || C_GDBSERVER
  4840. // #define CPU_CHECK_EXCEPT 1
  4841. // #define CPU_CHECK_IGNORE 1
  4842. /* Use CHECK_EXCEPT when something doesn't work to see if a exception is
  4843. @@ -546,6 +546,10 @@
  4844. void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) {
  4845. lastint=num;
  4846. FillFlags();
  4847. +#if C_GDBSERVER
  4848. + if (type == 0)
  4849. + DEBUG_IrqBreakpoint(num);
  4850. +#endif
  4851. #if C_DEBUG
  4852. switch (num) {
  4853. case 0xcd:
  4854. Index: src/cpu/core_full/op.h
  4855. ===================================================================
  4856. --- src/cpu/core_full/op.h (revision 3761)
  4857. +++ src/cpu/core_full/op.h (working copy)
  4858. @@ -356,12 +356,12 @@
  4859. CPU_JMP(true,inst_op2_d,inst_op1_d,GetIP());
  4860. continue;
  4861. case O_INT:
  4862. -#if C_DEBUG
  4863. +#if C_DEBUG || C_GDBSERVER
  4864. FillFlags();
  4865. if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint())
  4866. - return debugCallback;
  4867. + return DEBUG_debugCallback;
  4868. else if (DEBUG_IntBreakpoint(inst_op1_b))
  4869. - return debugCallback;
  4870. + return DEBUG_debugCallback;
  4871. #endif
  4872. CPU_SW_Interrupt(inst_op1_b,GetIP());
  4873. continue;
  4874. Index: src/cpu/core_dynrec.cpp
  4875. ===================================================================
  4876. --- src/cpu/core_dynrec.cpp (revision 3761)
  4877. +++ src/cpu/core_dynrec.cpp (working copy)
  4878. @@ -107,7 +107,7 @@
  4879. BR_Cycles,
  4880. BR_Link1,BR_Link2,
  4881. BR_Opcode,
  4882. -#if (C_DEBUG)
  4883. +#if C_DEBUG || C_GDBSERVER
  4884. BR_OpcodeFull,
  4885. #endif
  4886. BR_Iret,
  4887. @@ -186,8 +186,8 @@
  4888. for (;;) {
  4889. // Determine the linear address of CS:EIP
  4890. PhysPt ip_point=SegPhys(cs)+reg_eip;
  4891. - #if C_HEAVY_DEBUG
  4892. - if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
  4893. + #if C_HEAVY_DEBUG || C_GDBSERVER
  4894. + if (DEBUG_HeavyIsBreakpoint()) return DEBUG_debugCallback;
  4895. #endif
  4896.  
  4897. CodePageHandlerDynRec * chandler=0;
  4898. @@ -231,8 +231,8 @@
  4899.  
  4900. switch (ret) {
  4901. case BR_Iret:
  4902. -#if C_HEAVY_DEBUG
  4903. - if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
  4904. +#if C_HEAVY_DEBUG || C_GDBSERVER
  4905. + if (DEBUG_HeavyIsBreakpoint()) return DEBUG_debugCallback;
  4906. #endif
  4907. if (!GETFLAG(TF)) {
  4908. if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
  4909. @@ -247,16 +247,16 @@
  4910. // modifying instruction (like ret) or some nontrivial cpu state
  4911. // changing instruction (for example switch to/from pmode),
  4912. // or the maximum number of instructions to translate was reached
  4913. -#if C_HEAVY_DEBUG
  4914. - if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
  4915. +#if C_HEAVY_DEBUG || C_GDBSERVER
  4916. + if (DEBUG_HeavyIsBreakpoint()) return DEBUG_debugCallback;
  4917. #endif
  4918. break;
  4919.  
  4920. case BR_Cycles:
  4921. // cycles went negative, return from the core to handle
  4922. // external events, schedule the pic...
  4923. -#if C_HEAVY_DEBUG
  4924. - if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
  4925. +#if C_HEAVY_DEBUG || C_GDBSERVER
  4926. + if (DEBUG_HeavyIsBreakpoint()) return DEBUG_debugCallback;
  4927. #endif
  4928. return CBRET_NONE;
  4929.  
  4930. @@ -277,7 +277,7 @@
  4931. CPU_Cycles=1;
  4932. return CPU_Core_Normal_Run();
  4933.  
  4934. -#if (C_DEBUG)
  4935. +#if C_DEBUG || C_GDBSERVER
  4936. case BR_OpcodeFull:
  4937. CPU_CycleLeft+=CPU_Cycles;
  4938. CPU_Cycles=1;
  4939. Index: src/misc/support.cpp
  4940. ===================================================================
  4941. --- src/misc/support.cpp (revision 3761)
  4942. +++ src/misc/support.cpp (working copy)
  4943. @@ -171,7 +171,7 @@
  4944.  
  4945. static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95)
  4946. void E_Exit(const char * format,...) {
  4947. -#if C_DEBUG && C_HEAVY_DEBUG
  4948. +#if C_HEAVY_DEBUG || C_GDBSERVER
  4949. DEBUG_HeavyWriteLogInstruction();
  4950. #endif
  4951. va_list msg;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement