Worked started for the source tracing
authorJean-Paul Mari <djipi.mari@gmail.com>
Wed, 2 Oct 2019 19:02:34 +0000 (15:02 -0400)
committerJean-Paul Mari <djipi.mari@gmail.com>
Wed, 2 Oct 2019 19:02:34 +0000 (15:02 -0400)
14 files changed:
Win-VS2017/virtualjaguar.vcxproj.filters
docs/vj_HistoryNotes.txt
src/debugger/DBGManager.cpp
src/debugger/DBGManager.h
src/debugger/DWARFManager.cpp
src/debugger/DWARFManager.h
src/debugger/FilesrcListWin.cpp
src/debugger/SourceCWin.cpp [new file with mode: 0644]
src/debugger/SourceCWin.h [new file with mode: 0644]
src/debugger/SourcesWin.cpp [new file with mode: 0644]
src/debugger/SourcesWin.h [new file with mode: 0644]
src/gui/mainwin.cpp
src/gui/mainwin.h
virtualjaguar.pro

index 6c74ae9..d7b9722 100644 (file)
     <ClCompile Include="..\src\gui\debug\hwregsblitterbrowser.cpp">\r
       <Filter>Source Files\alpine</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="GeneratedFiles\Debug\moc_SourcesWin.cpp">\r
+      <Filter>Generated Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\src\debugger\SourcesWin.cpp">\r
+      <Filter>Source Files\debugger</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="GeneratedFiles\Release\moc_SourcesWin.cpp">\r
+      <Filter>Generated Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="..\src\debugger\SourceCWin.cpp">\r
+      <Filter>Source Files\debugger</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="GeneratedFiles\Debug\moc_SourceCWin.cpp">\r
+      <Filter>Generated Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="GeneratedFiles\Release\moc_SourceCWin.cpp">\r
+      <Filter>Generated Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\src\debugger\DWARFManager.h">\r
     <CustomBuild Include="..\src\gui\debug\hwregsblitterbrowser.h">\r
       <Filter>Header Files\alpine</Filter>\r
     </CustomBuild>\r
+    <CustomBuild Include="..\src\debugger\SourcesWin.h">\r
+      <Filter>Header Files\debugger</Filter>\r
+    </CustomBuild>\r
+    <CustomBuild Include="..\src\debugger\SourceCWin.h">\r
+      <Filter>Header Files\debugger</Filter>\r
+    </CustomBuild>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include="..\res\vj.rc">\r
index fd9fc6c..b39c710 100644 (file)
@@ -7,6 +7,7 @@ Release 5 (TBA)
 2) Added a specific breakpoint for the M68K address error exception
 -- Alert box will display a message and then the code will stop
 3) Added a HW registers browser window and set a tab for the Blitter
+4) Added a source tab in the main window for step into tracing
 
 Release 4a (15th August 2019)
 -----------------------------
@@ -227,8 +228,9 @@ Known issues
 15) After a new breakpoint set, the breakpoint list window is not refreshed
 -- User must perform an operation, such code tracing, to see the breakpoints list update
 16) Some ASCII characters may be not displayed correctly
--- It depend how the text is displayed, this is related to the QT/HTML encoding done when reading DWARF file
+-- Probably depend how the text is displayed, this is related to the QT/HTML encoding done when reading DWARF file
 17) Potential legacy crash when leaving emulator in pause mode for a long period of time
+-- Need much investigation
 
 Cosmetic / UX issues
 ====================
index 3dcb138..d86ecf9 100644 (file)
@@ -12,6 +12,7 @@
 // JPM              Various efforts to set the DWARF format support\r
 // JPM  09/15/2018  Support the unsigned char\r
 // JPM   Oct./2018  Cosmetic changes, added source file search paths, and ELF function name\r
+// JPM   Aug./2019  Added new functions mainly for source text lines\r
 //\r
 \r
 // To Do\r
@@ -746,19 +747,33 @@ char *DBGManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)
 \r
 \r
 // Get number of source code filenames\r
-size_t DBGManager_GetNbFullSourceFilename(void)\r
+size_t DBGManager_GetNbSources(void)\r
 {\r
        size_t Nbr = 0;\r
 \r
        if ((DBGType & DBG_ELFDWARF))\r
        {\r
-               Nbr = DWARFManager_GetNbFullSourceFilename();\r
+               Nbr = DWARFManager_GetNbSources();\r
        }\r
 \r
        return Nbr;\r
 }\r
 \r
 \r
+// Get source code filename based on index\r
+char *DBGManager_GetNumSourceFilename(size_t Index)\r
+{\r
+       char *SourceFilename = NULL;\r
+\r
+       if ((DBGType & DBG_ELFDWARF))\r
+       {\r
+               SourceFilename = DWARFManager_GetNumSourceFilename(Index);\r
+       }\r
+\r
+       return  SourceFilename;\r
+}\r
+\r
+\r
 // Get source code filename based on index\r
 char *DBGManager_GetNumFullSourceFilename(size_t Index)\r
 {\r
@@ -771,3 +786,60 @@ char *DBGManager_GetNumFullSourceFilename(size_t Index)
 \r
        return  FullSourceFilename;\r
 }\r
+\r
+\r
+// Get number of lines of texts source list from source index\r
+size_t DBGManager_GetSrcNbListPtrFromIndex(size_t Index, bool Used)\r
+{\r
+       size_t NbListPtr = 0;\r
+\r
+       if ((DBGType & DBG_ELFDWARF))\r
+       {\r
+               NbListPtr = DWARFManager_GetSrcNbListPtrFromIndex(Index, Used);\r
+       }\r
+\r
+       return  NbListPtr;\r
+}\r
+\r
+\r
+// Get pointer to the lines number list from source index\r
+size_t *DBGManager_GetSrcNumLinesPtrFromIndex(size_t Index, bool Used)\r
+{\r
+       size_t *PtrNumLines = NULL;\r
+\r
+       if ((DBGType & DBG_ELFDWARF))\r
+       {\r
+               PtrNumLines = DWARFManager_GetSrcNumLinesPtrFromIndex(Index, Used);\r
+       }\r
+\r
+       return  PtrNumLines;\r
+}\r
+\r
+\r
+// Get text source list pointers from source index\r
+char **DBGManager_GetSrcListPtrFromIndex(size_t Index, bool Used)\r
+{\r
+       char **PtrSource = NULL;\r
+\r
+       if ((DBGType & DBG_ELFDWARF))\r
+       {\r
+               PtrSource = DWARFManager_GetSrcListPtrFromIndex(Index, Used);\r
+       }\r
+\r
+       return  PtrSource;\r
+}\r
+\r
+\r
+// Get source language\r
+size_t DBGManager_GetSrcLanguageFromIndex(size_t Index)\r
+{\r
+       size_t Language = 0;\r
+\r
+       if ((DBGType & DBG_ELFDWARF))\r
+       {\r
+               Language = DWARFManager_GetSrcLanguageFromIndex(Index);\r
+       }\r
+\r
+       return  Language;\r
+}\r
+\r
index f034621..09cabc1 100644 (file)
@@ -4,6 +4,16 @@
 #define __DBGMANAGER_H__\r
 \r
 \r
+// Language tag based in the DW_TAG_... list from the dwarf.h\r
+typedef enum {\r
+       DBG_NO_LANG = 0x0,\r
+       DBG_LANG_C89 = 0x1,\r
+       DBG_LANG_C99 = 0xc,\r
+       DBG_LANG_VASM_Assembler = 0x8001,               // source from vasm assembler is marked as "DW_LANG_Mips_Assembler" with same value\r
+       DBG_END_LANG\r
+}DBGLANGTAG;\r
+\r
+// Debug types\r
 typedef enum {\r
        DBG_NO_TYPE = 0x0,\r
        DBG_ELF = 0x1,\r
@@ -227,15 +237,20 @@ extern size_t DBGManager_GetType(void);
 extern void    DBGManager_Reset(void);\r
 extern void    DBGManager_Close(void);\r
 extern void DBGManager_SourceFileSearchPathsSet(char *ListPaths);\r
+extern size_t DBGManager_GetNbSources(void);\r
 \r
 // Source text lines manager\r
 extern size_t DBGManager_GetNumLineFromAdr(size_t Adr, size_t Tag);\r
 extern char *DBGManager_GetLineSrcFromAdr(size_t Adr, size_t Tag);\r
 extern char *DBGManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine);\r
 extern char *DBGManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine);\r
+extern char **DBGManager_GetSrcListPtrFromIndex(size_t Index, bool Used);\r
+extern size_t DBGManager_GetSrcNbListPtrFromIndex(size_t Index, bool Used);\r
+extern size_t *DBGManager_GetSrcNumLinesPtrFromIndex(size_t Index, bool Used);\r
 \r
 // General manager\r
 extern char *DBGManager_GetVariableValueFromAdr(size_t Adr, size_t TypeEncoding, size_t TypeByteSize);\r
+extern size_t DBGManager_GetSrcLanguageFromIndex(size_t Index);\r
 \r
 // Functions manager\r
 extern char *DBGManager_GetFunctionName(size_t Adr);\r
@@ -246,8 +261,8 @@ extern size_t DBGManager_GetAdrFromSymbolName(char *SymbolName);
 \r
 // Source text files manager\r
 extern char    *DBGManager_GetFullSourceFilenameFromAdr(size_t Adr, bool *Error);\r
-extern size_t DBGManager_GetNbFullSourceFilename(void);\r
 extern char *DBGManager_GetNumFullSourceFilename(size_t Index);\r
+extern char *DBGManager_GetNumSourceFilename(size_t Index);\r
 \r
 // Global variables manager\r
 extern size_t DBGManager_GetNbGlobalVariables(void);\r
index fed680a..b65227f 100644 (file)
@@ -10,6 +10,7 @@
 // JPM   Dec./2016  Created this file, and added the DWARF format support\r
 // JPM  Sept./2018  Added LEB128 decoding features, and improve the DWARF parsing information\r
 // JPM   Oct./2018  Improve the DWARF parsing information, and the source file text reading; support the used source lines from DWARF structure, and the search paths for the files\r
+// JPM   Aug./2019  Added new functions to handle DWARF information, full filename fix\r
 //\r
 \r
 // To Do\r
 \r
 \r
 // Definitions for debugging\r
-//#define DEBUG_NumCU                  0x4d                            // CU number to debug or undefine it\r
+//#define DEBUG_NumCU                  0x44                            // CU number to debug or undefine it\r
 //#define DEBUG_VariableName   "sound_death"                           // Variable name to look for or undefine it\r
 //#define DEBUG_TypeName               "Cbuf_Execute"                  // Type name to look for or undefine it\r
 //#define DEBUG_TypeDef                        DW_TAG_typedef          // Type def to look for or undefine it (not supported)\r
-//#define DEBUG_Filename               "net_jag.c"                     // Filename to look for or undefine it\r
+//#define DEBUG_Filename               "crt0"                  // Filename to look for or undefine it\r
+\r
+// Definitions for handling data\r
+//#define CONVERT_QT_HML                                                               // Text will be converted as HTML\r
 \r
 // Definitions for the variables's typetag\r
 #define        TypeTag_structure                       0x01                    // structure\r
@@ -125,6 +129,7 @@ typedef struct SubProgStruct
 typedef struct CUStruct\r
 {\r
        size_t Tag;\r
+       size_t Language;                                                                // Language (C, etc.) used by the source code\r
        size_t LowPC, HighPC;                                                   // Memory range for the code\r
        char *PtrProducer;                                                              // Pointer to the "Producer" text information (mostly compiler and compilation options used)\r
        char *PtrSourceFilename;                                                // Source file name\r
@@ -141,8 +146,11 @@ typedef struct CUStruct
        size_t NbVariables;                                                             // Variables number\r
        VariablesStruct *PtrVariables;                                  // Pointer to the global variables list structure\r
        size_t NbFrames;                                                                // Frames number\r
-       size_t NbLinesSrc;                                                              // Number of used source lines\r
-       CUStruct_LineSrc *PtrLinesSrc;                                  // Pointer to the used source lines list structure\r
+       size_t NbUsedLinesSrc;                                                  // Number of used source lines\r
+       size_t LastNumUsedLinesSrc;                                             // Last used source number line\r
+       CUStruct_LineSrc *PtrUsedLinesSrc;                              // Pointer to the used source lines list structure\r
+       char **PtrUsedLinesLoadSrc;                                             // Pointer lists to each used source line referenced by the CUStruct_LineSrc structure\r
+       size_t *PtrUsedNumLines;                                                // Pointer list to the number lines used\r
 }S_CUStruct;\r
 \r
 \r
@@ -167,6 +175,7 @@ void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables);
 void DWARFManager_SourceFileSearchPathsInit(void);\r
 void DWARFManager_SourceFileSearchPathsReset(void);\r
 void DWARFManager_SourceFileSearchPathsClose(void);\r
+void DWARFManager_ConformSlachesBackslashes(char *Ptr);\r
 \r
 \r
 //\r
@@ -278,7 +287,9 @@ void DWARFManager_CloseDMI(void)
                free(PtrCU[NbCU].PtrProducer);\r
                free(PtrCU[NbCU].PtrSourceFilename);\r
                free(PtrCU[NbCU].PtrSourceFileDirectory);\r
-               free(PtrCU[NbCU].PtrLinesSrc);\r
+               free(PtrCU[NbCU].PtrUsedLinesSrc);\r
+               free(PtrCU[NbCU].PtrUsedLinesLoadSrc);\r
+               free(PtrCU[NbCU].PtrUsedNumLines);\r
 \r
                while (PtrCU[NbCU].NbLinesLoadSrc--)\r
                {\r
@@ -426,6 +437,14 @@ void DWARFManager_InitDMI(void)
                                                                                        }\r
                                                                                        break;\r
 \r
+                                                                                       // Language\r
+                                                                               case DW_AT_language:\r
+                                                                                       if (dwarf_formudata(atlist[i], &return_uvalue, &error) == DW_DLV_OK)\r
+                                                                                       {\r
+                                                                                               PtrCU[NbCU].Language = return_uvalue;\r
+                                                                                       }\r
+                                                                                       break;\r
+\r
                                                                                default:\r
                                                                                        break;\r
                                                                                }\r
@@ -468,30 +487,29 @@ void DWARFManager_InitDMI(void)
                                                                }\r
                                                        }\r
 \r
-                                                       // Create full filename\r
-                                                       Ptr = PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + strlen(PtrCU[NbCU].PtrSourceFileDirectory) + 2);\r
-#if defined(_WIN32)\r
-                                                       sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
-#else\r
-                                                       sprintf(PtrCU[NbCU].PtrFullFilename, "%s/%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
-#endif\r
-                                                       // Conform slashes and backslashes\r
-                                                       while (*Ptr)\r
+                                                       // Conform slashes / backslashes for the filename\r
+                                                       DWARFManager_ConformSlachesBackslashes(PtrCU[NbCU].PtrSourceFilename);\r
+\r
+                                                       // Check if filename contains already the complete directory\r
+                                                       if (PtrCU[NbCU].PtrSourceFilename[1] == ':')\r
+                                                       {\r
+                                                               // Copy the filename as the full filename\r
+                                                               PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + 1);\r
+                                                               strcpy(PtrCU[NbCU].PtrFullFilename, PtrCU[NbCU].PtrSourceFilename);\r
+                                                       }\r
+                                                       else\r
                                                        {\r
+                                                               // Create full filename and Conform slashes / backslashes\r
+                                                               PtrCU[NbCU].PtrFullFilename = (char *)realloc(PtrCU[NbCU].PtrFullFilename, strlen(PtrCU[NbCU].PtrSourceFilename) + strlen(PtrCU[NbCU].PtrSourceFileDirectory) + 2);\r
 #if defined(_WIN32)\r
-                                                               if (*Ptr == '/')\r
-                                                               {\r
-                                                                       *Ptr = '\\';\r
-                                                               }\r
+                                                               sprintf(PtrCU[NbCU].PtrFullFilename, "%s\\%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
 #else\r
-                                                               if (*Ptr == '\\')\r
-                                                               {\r
-                                                                       *Ptr = '/';\r
-                                                               }\r
+                                                               sprintf(PtrCU[NbCU].PtrFullFilename, "%s/%s", PtrCU[NbCU].PtrSourceFileDirectory, PtrCU[NbCU].PtrSourceFilename);\r
 #endif\r
-                                                               Ptr++;\r
                                                        }\r
 \r
+                                                       DWARFManager_ConformSlachesBackslashes(PtrCU[NbCU].PtrFullFilename);\r
+\r
                                                        // Directory path clean-up\r
 #if defined(_WIN32)\r
                                                        while ((Ptr1 = Ptr = strstr(PtrCU[NbCU].PtrFullFilename, "\\..\\")))\r
@@ -579,16 +597,26 @@ void DWARFManager_InitDMI(void)
                                        {\r
                                                if (cnt)\r
                                                {\r
-                                                       PtrCU[NbCU].NbLinesSrc = cnt;\r
-                                                       PtrCU[NbCU].PtrLinesSrc = (CUStruct_LineSrc *)calloc(cnt, sizeof(CUStruct_LineSrc));\r
+                                                       PtrCU[NbCU].NbUsedLinesSrc = cnt;\r
+                                                       PtrCU[NbCU].PtrUsedLinesSrc = (CUStruct_LineSrc *)calloc(cnt, sizeof(CUStruct_LineSrc));\r
+                                                       PtrCU[NbCU].PtrUsedLinesLoadSrc = (char **)calloc(cnt, sizeof(char *));\r
+                                                       PtrCU[NbCU].PtrUsedNumLines = (size_t *)calloc(cnt, sizeof(size_t));\r
+\r
+                                                       // Get the addresses and their source line numbers\r
                                                        for (Dwarf_Signed i = 0; i < cnt; i++)\r
                                                        {\r
                                                                if (dwarf_lineaddr(linebuf[i], &return_lineaddr, &error) == DW_DLV_OK)\r
                                                                {\r
                                                                        if (dwarf_lineno(linebuf[i], &return_uvalue, &error) == DW_DLV_OK)\r
                                                                        {\r
-                                                                               PtrCU[NbCU].PtrLinesSrc[i].StartPC = return_lineaddr;\r
-                                                                               PtrCU[NbCU].PtrLinesSrc[i].NumLineSrc = return_uvalue;\r
+                                                                               PtrCU[NbCU].PtrUsedLinesSrc[i].StartPC = return_lineaddr;\r
+                                                                               PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc = return_uvalue;\r
+\r
+                                                                               // Get the last used line number in the source file\r
+                                                                               if (PtrCU[NbCU].LastNumUsedLinesSrc < PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc)\r
+                                                                               {\r
+                                                                                       PtrCU[NbCU].LastNumUsedLinesSrc = PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc;\r
+                                                                               }\r
                                                                        }\r
                                                                }\r
                                                        }\r
@@ -1041,6 +1069,7 @@ void DWARFManager_InitDMI(void)
                                                                        {\r
                                                                                switch (*Ptr)\r
                                                                                {\r
+#ifdef CONVERT_QT_HML\r
                                                                                case 9:\r
                                                                                        strcat(PtrCU[NbCU].PtrLinesLoadSrc[j], "&nbsp;");\r
                                                                                        i += 6;\r
@@ -1066,6 +1095,7 @@ void DWARFManager_InitDMI(void)
                                                                                        strcpy(PtrCU[NbCU].PtrLinesLoadSrc[j], "&quot;");\r
                                                                                        i += strlen("&quot;");\r
                                                                                        break;\r
+#endif\r
 #endif\r
                                                                                default:\r
                                                                                        PtrCU[NbCU].PtrLinesLoadSrc[j][i++] = *Ptr;\r
@@ -1117,23 +1147,28 @@ void DWARFManager_InitDMI(void)
                                        }\r
                                }\r
 \r
-                               // Set information based on used line numbers\r
-                               if (PtrCU[NbCU].PtrLinesSrc)\r
+                               // Check validity between used number lines and number lines in the source file\r
+                               if (PtrCU[NbCU].LastNumUsedLinesSrc <= PtrCU[NbCU].NbLinesLoadSrc)\r
                                {\r
-                                       // Set the line source pointer for each used line numbers\r
-                                       if (PtrCU[NbCU].PtrLinesLoadSrc)\r
+                                       // Set information based on used line numbers\r
+                                       if (PtrCU[NbCU].PtrUsedLinesSrc)\r
                                        {\r
-                                               for (size_t i = 0; i < PtrCU[NbCU].NbLinesSrc; i++)\r
+                                               // Set the line source pointers for each used line numbers\r
+                                               if (PtrCU[NbCU].PtrLinesLoadSrc)\r
                                                {\r
-                                                       PtrCU[NbCU].PtrLinesSrc[i].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrLinesSrc[i].NumLineSrc - 1];\r
-                                               }\r
+                                                       for (size_t i = 0; i < PtrCU[NbCU].NbUsedLinesSrc; i++)\r
+                                                       {\r
+                                                               PtrCU[NbCU].PtrUsedNumLines[i] = PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc - 1;\r
+                                                               PtrCU[NbCU].PtrUsedLinesLoadSrc[i] = PtrCU[NbCU].PtrUsedLinesSrc[i].PtrLineSrc = PtrCU[NbCU].PtrLinesLoadSrc[PtrCU[NbCU].PtrUsedLinesSrc[i].NumLineSrc - 1];\r
+                                                       }\r
 \r
-                                               // Setup memory range for the code if CU doesn't have already this information\r
-                                               // It is taken from the used lines structure\r
-                                               if (!PtrCU[NbCU].LowPC && (!PtrCU[NbCU].HighPC || (PtrCU[NbCU].HighPC == ~0)))\r
-                                               {\r
-                                                       PtrCU[NbCU].LowPC = PtrCU[NbCU].PtrLinesSrc[0].StartPC;\r
-                                                       PtrCU[NbCU].HighPC = PtrCU[NbCU].PtrLinesSrc[PtrCU[NbCU].NbLinesSrc - 1].StartPC;\r
+                                                       // Setup memory range for the code if CU doesn't have already this information\r
+                                                       // It is taken from the used lines structure\r
+                                                       if (!PtrCU[NbCU].LowPC && (!PtrCU[NbCU].HighPC || (PtrCU[NbCU].HighPC == ~0)))\r
+                                                       {\r
+                                                               PtrCU[NbCU].LowPC = PtrCU[NbCU].PtrUsedLinesSrc[0].StartPC;\r
+                                                               PtrCU[NbCU].HighPC = PtrCU[NbCU].PtrUsedLinesSrc[PtrCU[NbCU].NbUsedLinesSrc - 1].StartPC;\r
+                                                       }\r
                                                }\r
                                        }\r
                                }\r
@@ -1160,6 +1195,27 @@ void DWARFManager_InitDMI(void)
 }\r
 \r
 \r
+// Conform slashes and backslashes\r
+void DWARFManager_ConformSlachesBackslashes(char *Ptr)\r
+{\r
+       while (*Ptr)\r
+       {\r
+#if defined(_WIN32)\r
+               if (*Ptr == '/')\r
+               {\r
+                       *Ptr = '\\';\r
+               }\r
+#else\r
+               if (*Ptr == '\\')\r
+               {\r
+                       *Ptr = '/';\r
+               }\r
+#endif\r
+               Ptr++;\r
+       }\r
+}\r
+\r
+\r
 // Variables information initialisation\r
 void DWARFManager_InitInfosVariable(VariablesStruct *PtrVariables)\r
 {\r
@@ -1803,11 +1859,11 @@ size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag)
                        }\r
 \r
                        // Check if a used line is found with the address\r
-                       for (size_t j = 0; j < PtrCU[i].NbLinesSrc; j++)\r
+                       for (size_t j = 0; j < PtrCU[i].NbUsedLinesSrc; j++)\r
                        {\r
-                               if (PtrCU[i].PtrLinesSrc[j].StartPC == Adr)\r
+                               if (PtrCU[i].PtrUsedLinesSrc[j].StartPC == Adr)\r
                                {\r
-                                       return PtrCU[i].PtrLinesSrc[j].NumLineSrc;\r
+                                       return PtrCU[i].PtrUsedLinesSrc[j].NumLineSrc;\r
                                }\r
                        }\r
                }\r
@@ -1839,6 +1895,57 @@ char *DWARFManager_GetFunctionName(size_t Adr)
 }\r
 \r
 \r
+// Get number of lines of texts source list from source index\r
+size_t DWARFManager_GetSrcNbListPtrFromIndex(size_t Index, bool Used)\r
+{\r
+       if (!Used)\r
+       {\r
+               return PtrCU[Index].NbLinesLoadSrc;\r
+       }\r
+       else\r
+       {\r
+               return PtrCU[Index].NbUsedLinesSrc;\r
+       }\r
+}\r
+\r
+\r
+// Get text source line number list pointer from source index\r
+// Return NULL for the text source used list \r
+size_t *DWARFManager_GetSrcNumLinesPtrFromIndex(size_t Index, bool Used)\r
+{\r
+       if (Used)\r
+       {\r
+               return  PtrCU[Index].PtrUsedNumLines;\r
+       }\r
+       else\r
+       {\r
+               return NULL;\r
+       }\r
+}\r
+\r
+\r
+// Get text source list pointers from source index\r
+// Return NULL for the text source used list \r
+char **DWARFManager_GetSrcListPtrFromIndex(size_t Index, bool Used)\r
+{\r
+       if (!Used)\r
+       {\r
+               return PtrCU[Index].PtrLinesLoadSrc;\r
+       }\r
+       else\r
+       {\r
+               return PtrCU[Index].PtrUsedLinesLoadSrc;\r
+       }\r
+}\r
+\r
+\r
+// Get source language\r
+size_t DWARFManager_GetSrcLanguageFromIndex(size_t Index)\r
+{\r
+       return PtrCU[Index].Language;\r
+}\r
+\r
+\r
 // Get text line from source based on address and num line (starting from 1)\r
 // Return NULL if no text line has been found\r
 char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine)\r
@@ -1898,15 +2005,22 @@ char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine)
 \r
 \r
 // Get number of source code filenames\r
-size_t DWARFManager_GetNbFullSourceFilename(void)\r
+size_t DWARFManager_GetNbSources(void)\r
 {\r
        return NbCU;\r
 }\r
 \r
 \r
-// Get source code filename based on index (starting from 0)\r
+// Get source code filename, including his directory, based on index (starting from 0)\r
 char *DWARFManager_GetNumFullSourceFilename(size_t Index)\r
 {\r
        return (PtrCU[Index].PtrFullFilename);\r
 }\r
 \r
+\r
+// Get source code filename based on index (starting from 0)\r
+char *DWARFManager_GetNumSourceFilename(size_t Index)\r
+{\r
+       return (PtrCU[Index].PtrSourceFilename);\r
+}\r
+\r
index d05e4ee..9df4535 100644 (file)
@@ -10,14 +10,16 @@ extern bool DWARFManager_Close(void);
 extern void    DWARFManager_Init(void);\r
 extern int DWARFManager_ElfInit(Elf *ElfPtr);\r
 extern void DWARFManager_Set(size_t NbPathsInList, char **PtrListPaths);\r
+extern size_t DWARFManager_GetNbSources(void);\r
 \r
 // General manager\r
 extern char *DWARFManager_GetFunctionName(size_t Adr);\r
+extern size_t DWARFManager_GetSrcLanguageFromIndex(size_t Index);\r
 \r
 // Source text files manager\r
 extern char    *DWARFManager_GetFullSourceFilenameFromAdr(size_t Adr, bool *Error);\r
-extern size_t DWARFManager_GetNbFullSourceFilename(void);\r
 extern char *DWARFManager_GetNumFullSourceFilename(size_t Index);\r
+extern char *DWARFManager_GetNumSourceFilename(size_t Index);\r
 \r
 // Symbols manager\r
 extern char    *DWARFManager_GetSymbolnameFromAdr(size_t Adr);\r
@@ -27,6 +29,9 @@ extern size_t DWARFManager_GetNumLineFromAdr(size_t Adr, size_t Tag);
 extern char *DWARFManager_GetLineSrcFromAdr(size_t Adr, size_t Tag);\r
 extern char *DWARFManager_GetLineSrcFromAdrNumLine(size_t Adr, size_t NumLine);\r
 extern char *DWARFManager_GetLineSrcFromNumLineBaseAdr(size_t Adr, size_t NumLine);\r
+extern char **DWARFManager_GetSrcListPtrFromIndex(size_t Index, bool Used);\r
+extern size_t DWARFManager_GetSrcNbListPtrFromIndex(size_t Index, bool Used);\r
+extern size_t *DWARFManager_GetSrcNumLinesPtrFromIndex(size_t Index, bool Used);\r
 \r
 // Global variables manager\r
 extern size_t DWARFManager_GetNbGlobalVariables(void);\r
index ab0fb9c..5017db0 100644 (file)
@@ -104,7 +104,7 @@ size_t FilesrcListWindow::UpdateInfos(void)
 {
        size_t Nbr, i;
 
-       Nbr = DBGManager_GetNbFullSourceFilename();
+       Nbr = DBGManager_GetNbSources();
 
        for (i = 0; i < Nbr; i++)
        {
diff --git a/src/debugger/SourceCWin.cpp b/src/debugger/SourceCWin.cpp
new file mode 100644 (file)
index 0000000..a69edc2
--- /dev/null
@@ -0,0 +1,195 @@
+//
+//  SourceCWin.cpp - Source C tracing window
+//
+// by Jean-Paul Mari
+//
+// JPM = Jean-Paul Mari <djipi.mari@gmail.com>
+//
+// Who  When        What
+// ---  ----------  -------------------------------------------------------------
+// JPM  08/23/2019  Created this file
+
+// STILL TO DO:
+//
+
+#include <stdlib.h>
+#include "DBGManager.h"
+#include "debugger/SourceCWin.h"
+#include "debugger/SourcesWin.h"
+//#include "m68000/m68kinterface.h"
+
+
+// 
+SourceCWindow::SourceCWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),
+layout(new QVBoxLayout),
+FileIndex(0),
+CurrentNumLineSrc(0),
+#ifdef SC_LAYOUTTEXTS
+text(new QTextBrowser)
+#else
+TableView(new QTableView),
+model(new QStandardItemModel)
+#endif
+{
+       // Set font
+       QFont fixedFont("Lucida Console", 8, QFont::Normal);
+       fixedFont.setStyleHint(QFont::Monospace);   //TypeWriter
+       fixedFont.setLetterSpacing(QFont::PercentageSpacing, 100);
+
+       // Set text in layout
+#ifdef SC_LAYOUTTEXTS
+       text->setFont(fixedFont);
+       layout->addWidget(text);
+#else
+       // Set the new layout with proper identation and readibility
+       model->setColumnCount(3);
+       model->setHeaderData(0, Qt::Horizontal, QObject::tr("LineStatus"));
+       model->setHeaderData(1, Qt::Horizontal, QObject::tr("LineNumber"));
+       model->setHeaderData(2, Qt::Horizontal, QObject::tr("LineSrc"));
+       // Information table
+       TableView->setModel(model);
+       TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
+       TableView->setSelectionMode(QAbstractItemView::NoSelection);
+       TableView->setShowGrid(false);
+       TableView->horizontalHeader()->hide();
+       TableView->verticalHeader()->hide();
+       TableView->setFont(fixedFont);
+       layout->addWidget(TableView);
+#endif
+
+       // Set layout
+       setLayout(layout);
+}
+
+
+//
+void SourceCWindow::SetCursorTrace(int NumLineSrc, bool Remove)
+{
+       // Check valid line number
+       if (NumLineSrc && (NbLinesText[0] >= NumLineSrc))
+       {
+               // Set the trace cursor
+               if (!Remove)
+               {
+                       CurrentNumLineSrc = NumLineSrc;
+#ifndef SC_LAYOUTTEXTS
+                       model->item((NumLineSrc - 1), 0)->setText(">");
+                       model->item((NumLineSrc - 1), 0)->setBackground(QColor(0xff, 0xfa, 0xcd));
+                       model->item((NumLineSrc - 1), 1)->setBackground(QColor(0xff, 0xfa, 0xcd));
+                       model->item((NumLineSrc - 1), 2)->setBackground(QColor(0xff, 0xfa, 0xcd));
+#endif
+               }
+               else
+               {
+                       // Remove the trace cursor
+#ifndef SC_LAYOUTTEXTS
+                       model->item((NumLineSrc - 1), 0)->setText(" ");
+                       model->item((NumLineSrc - 1), 0)->setBackground(QColor(173, 216, 230));
+                       model->item((NumLineSrc - 1), 1)->setBackground(QColor(255, 255, 255));
+                       model->item((NumLineSrc - 1), 2)->setBackground(QColor(255, 255, 255));
+#endif
+               }
+       }
+}
+
+
+//
+void SourceCWindow::RefreshContents(void)
+{
+       if (isVisible())
+       {
+               // Get the scroll bar information
+               int MaxSlider = TableView->verticalScrollBar()->maximum();                                                      // Get the slider maximum position
+               int DeltaSlider = (int)NbLinesText[0] - MaxSlider;                                                                      // Number of items displayed in the scroll bar slider
+               //int PosSlider = TableView->verticalScrollBar()->sliderPosition();                                     // Slider position
+
+               // Check visibility in the scroll bar
+               //if ((CurrentNumLineSrc > PosSlider) && ((CurrentNumLineSrc + (DeltaSlider / 2)) < MaxSlider))
+               {
+                       // Set the scroll bar position 
+                       TableView->verticalScrollBar()->setSliderPosition(CurrentNumLineSrc - (DeltaSlider / 2) - 1);
+               }
+       }
+}
+
+
+// Fill the tab with the source text
+void SourceCWindow::FillTab(size_t index, char **TextLines, size_t NbLines[], size_t *NumLinesUsed)
+{
+       int i, j, k;
+#ifdef SC_LAYOUTTEXTS
+       QString s;
+       char string[1024];
+#endif
+
+       // Save information
+       FileIndex = index;
+       for (i = 0; i < 2; i++)
+       {
+               NbLinesText[i] = NbLines[i];
+       }
+       PtrTextLines = TextLines;
+       PtrNumLinesUsed = NumLinesUsed;
+
+       // Set columns
+#ifndef SC_LAYOUTTEXTS
+       model->insertRow((int)NbLinesText[0]);
+#endif
+
+       // Set text lines
+       for (i = j = 0; i < NbLinesText[0]; i++, j = 0)
+       {
+               // prepare space for the line status
+#ifndef SC_LAYOUTTEXTS
+               model->setItem(i, 0, new QStandardItem(QString("%1").arg(" ")));
+               model->item(i, 0)->setTextAlignment(Qt::AlignCenter);
+               model->item(i, 0)->setBackground(QColor(173, 216, 230));
+#endif
+               // display line number
+#ifdef SC_LAYOUTTEXTS
+               sprintf(string, "| <font color='#006400'>%5u</font> | ", (i + 1));
+               s += QString(string);
+#else
+               model->setItem(i, 1, new QStandardItem(QString(" %1 ").arg((i + 1))));
+               model->item(i, 1)->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
+               model->item(i, 1)->setForeground(QColor(0, 0x64, 0));
+#endif
+               // display source code line
+#ifndef SC_LAYOUTTEXTS
+               model->setItem(i, 2, new QStandardItem(QString("%1").arg(PtrTextLines[i])));
+               model->item(i, 2)->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+#endif
+               // Check line used by code
+               while ((j < NbLinesText[1]) && !(k = ((PtrNumLinesUsed[j++] != i) - 1)));
+               if (k)
+               {
+                       // Line is used by code
+#ifdef SC_LAYOUTTEXTS
+                       sprintf(string, "<font color='#000000'><b>%s</b></font>", PtrTextLines[i]);
+#else
+                       model->item(i, 2)->setForeground(QColor(0, 0, 0));
+#endif
+               }
+               else
+               {
+                       // Line is not used by code (such as comments)
+#ifdef SC_LAYOUTTEXTS
+                       sprintf(string, "<font color='#C8C8C8'>%s</font>", PtrTextLines[i]);
+#else
+                       model->item(i, 2)->setForeground(QColor(0xc8, 0xc8, 0xc8));
+#endif
+               }
+#ifdef SC_LAYOUTTEXTS
+               s += QString(string);
+               s += QString("<br>");
+#endif
+       }
+
+       // Display text
+#ifdef SC_LAYOUTTEXTS
+       text->setText(s);
+#else
+       TableView->resizeColumnsToContents();
+       TableView->resizeRowsToContents();
+#endif
+}
diff --git a/src/debugger/SourceCWin.h b/src/debugger/SourceCWin.h
new file mode 100644 (file)
index 0000000..5f39233
--- /dev/null
@@ -0,0 +1,49 @@
+//
+// SourcesWin.h: Source C tracing window
+//
+// JPM = Jean-Paul Mari <djipi.mari@gmail.com>
+//
+// Who  When        What
+// ---  ----------  -------------------------------------------------------------
+// JPM  08/23/2019  Created this file
+//
+
+#ifndef __SOURCECWIN_H__
+#define __SOURCECWIN_H__
+
+//#define SC_LAYOUTTEXTS                                               // Use a layout with just texts
+
+#include <QtWidgets>
+//#include <stdint.h>
+
+
+class SourceCWindow : public QWidget
+{
+       Q_OBJECT
+
+public:
+       SourceCWindow(QWidget * parent = 0);
+       void FillTab(size_t index, char **TextLines, size_t NbLines[], size_t *NumLinesUsed);
+       void SetCursorTrace(int NumLineSrc, bool Remove);
+
+public slots:
+       void RefreshContents(void);
+
+protected:
+
+private:
+       size_t FileIndex;
+       int CurrentNumLineSrc;
+       QVBoxLayout *layout;
+#ifdef SC_LAYOUTTEXTS
+       QTextBrowser *text;
+#else
+       QTableView *TableView;
+       QStandardItemModel *model;
+#endif
+       char **PtrTextLines;
+       size_t NbLinesText[2];
+       size_t *PtrNumLinesUsed;
+};
+
+#endif
diff --git a/src/debugger/SourcesWin.cpp b/src/debugger/SourcesWin.cpp
new file mode 100644 (file)
index 0000000..0dfa87e
--- /dev/null
@@ -0,0 +1,263 @@
+//
+//  SourcesWin.cpp - Sources tracing window
+//
+// by Jean-Paul Mari
+//
+// JPM = Jean-Paul Mari <djipi.mari@gmail.com>
+//
+// Who  When        What
+// ---  ----------  -------------------------------------------------------------
+// JPM  08/23/2019  Created this file
+
+// STILL TO DO:
+//
+
+#include <stdlib.h>
+#include <string.h>
+#include "DBGManager.h"
+#include "debugger/SourceCWin.h"
+#include "debugger/SourcesWin.h"
+#include "m68000/m68kinterface.h"
+
+
+// 
+SourcesWindow::SourcesWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),
+layout(new QVBoxLayout),
+sourcestabWidget(new QTabWidget),
+sourcesinfostab(0),
+NbSourcesInfos(0),
+CurrentTab(0),
+OldCurrentTab(0),
+OldCurrentNumLineSrc(0),
+indexErrorTab(-1),
+sourceErrorTab(0)
+{
+       // Prepare layout
+       sourcestabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+       sourcestabWidget->setTabsClosable(true);
+       layout->addWidget(sourcestabWidget);
+
+       // Set layout
+       setLayout(layout);
+
+       // Connect the signals
+       connect(sourcestabWidget, SIGNAL(currentChanged(const int)), this, SLOT(SelectTab(const int)));
+       connect(sourcestabWidget, SIGNAL(tabCloseRequested(const int)), this, SLOT(CloseTab(const int)));
+}
+
+
+// Close tab
+void SourcesWindow::CloseTab(const int)
+{
+       CloseCurrentTab();
+}
+
+
+// Select tab
+void SourcesWindow::SelectTab(const int)
+{
+#if 0
+       size_t i = 0;
+       QString t = sourcestabWidget->tabText(index);
+       while ((i < NbSourcesInfos) && strcmp(sourcesinfostab[i++].Filename, t.toLatin1().data()));
+
+       if ((i != NbSourcesInfos) && (sourcesinfostab[i - 1].IndexTab != -1) && (CurrentTab == (i - 1)))
+       {
+               sourcesinfostab[(i - 1)].sourceCtab->RefreshContents();
+       }
+#endif
+}
+
+
+// Sources initialisation
+void SourcesWindow::Init(void)
+{
+       size_t i, j;
+       char *Ptr, *Ptr1;
+
+       // Get number of sources
+       NbSourcesInfos = DBGManager_GetNbSources();
+       if (NbSourcesInfos)
+       {
+               // Alloc structure for the source informations
+               sourcesinfostab = (SourcesInfos *)calloc(NbSourcesInfos, sizeof(SourcesInfos));
+
+               // Fill sources information
+               for (i = 0; i < NbSourcesInfos; i++)
+               {
+                       // Get source filename without misguiding information
+                       Ptr = DBGManager_GetNumSourceFilename(i);
+                       Ptr1 = sourcesinfostab[i].Filename = (char *)malloc(strlen(Ptr) + 1);
+                       while (((*Ptr == '.') || ((*Ptr == '/') || (*Ptr == '\\'))) && Ptr++);
+                       strcpy(Ptr1, Ptr);
+                       // Get texts dedicated information
+                       for (j = 0; j < 2; j++)
+                       {
+                               sourcesinfostab[i].NbLinesText[j] = DBGManager_GetSrcNbListPtrFromIndex(i, j);
+                       }
+                       sourcesinfostab[i].NumLinesUsed = DBGManager_GetSrcNumLinesPtrFromIndex(i, true);
+                       sourcesinfostab[i].SourceText = DBGManager_GetSrcListPtrFromIndex(i, false);
+                       // Get remaining information
+                       sourcesinfostab[i].Language = DBGManager_GetSrcLanguageFromIndex(i);
+                       sourcesinfostab[i].IndexTab = -1;
+               }
+       }
+}
+
+
+// Get the tracing status
+bool SourcesWindow::GetTraceStatus(void)
+{
+       if (NbSourcesInfos)
+       {
+               switch (sourcesinfostab[CurrentTab].Language)
+               {
+               case DBG_LANG_VASM_Assembler:
+                       break;
+
+               default:
+                       return true;
+                       break;
+               }
+       }
+
+       return false;
+}
+
+
+// Check if line has changed
+bool SourcesWindow::CheckChangeLine(void)
+{
+       size_t NumLine;
+
+       if (NumLine = DBGManager_GetNumLineFromAdr(m68k_get_reg(NULL, M68K_REG_PC), DBG_NO_TAG))
+       {
+               if (OldCurrentTab == CurrentTab)
+               {
+                       if (OldCurrentNumLineSrc != NumLine)
+                       {
+                               OldCurrentNumLineSrc = NumLine;
+                               return true;
+                       }
+               }
+               else
+               {
+                       OldCurrentTab = CurrentTab;
+                       OldCurrentNumLineSrc = 0;
+               }
+
+       }
+
+       return false;
+}
+
+
+//
+void SourcesWindow::RefreshContents(void)
+{
+       size_t m68kPC = m68k_get_reg(NULL, M68K_REG_PC);
+       int index = 0;
+       size_t i;
+       bool Error;
+       char *Filename;
+
+       // Check valid PC
+       if (m68kPC && NbSourcesInfos)
+       {
+               // Get source filename pointed by PC address
+               Filename = DBGManager_GetFullSourceFilenameFromAdr(m68kPC, &Error);
+               if (Error && Filename)
+               {
+                       // Look for a new tab
+                       for (i = 0; i < NbSourcesInfos; i++, !index)
+                       {
+                               if (sourcesinfostab[i].Filename)
+                               {
+                                       if (strstr(Filename, sourcesinfostab[i].Filename))
+                                       {
+                                               // Open a new tab for a source code
+                                               if (sourcesinfostab[i].IndexTab == -1)
+                                               {
+                                                       sourcesinfostab[i].IndexTab = index = sourcestabWidget->addTab(sourcesinfostab[i].sourceCtab = new(SourceCWindow), tr(sourcesinfostab[i].Filename));
+                                                       sourcesinfostab[i].sourceCtab->FillTab(i, sourcesinfostab[i].SourceText, sourcesinfostab[i].NbLinesText, sourcesinfostab[i].NumLinesUsed);
+                                               }
+
+                                               sourcestabWidget->setCurrentIndex(sourcesinfostab[i].IndexTab);
+                                               sourcesinfostab[CurrentTab].sourceCtab->SetCursorTrace(sourcesinfostab[CurrentTab].CurrentNumLineSrc, true);
+                                               sourcesinfostab[i].sourceCtab->SetCursorTrace(sourcesinfostab[i].CurrentNumLineSrc = (int)DBGManager_GetNumLineFromAdr(m68kPC, DBG_NO_TAG), false);
+                                               sourcesinfostab[i].sourceCtab->RefreshContents();
+                                               CurrentTab = i;
+                                       }
+                               }
+                       }
+               }
+               else
+               {
+                       // Source file doesn't exist
+                       if (indexErrorTab == -1)
+                       {
+                               indexErrorTab = sourcestabWidget->addTab(sourceErrorTab = new(SourceCWindow), tr("Source file not found"));
+                               //sourceErrorTab->hide();
+                       }
+                       sourcestabWidget->setCurrentIndex(indexErrorTab);
+               }
+       }
+}
+
+
+// Close / Remove current tab
+void SourcesWindow::CloseCurrentTab(void)
+{
+       size_t i = 0;
+       int Index;
+       QString t = sourcestabWidget->tabText((Index = sourcestabWidget->currentIndex()));
+
+       // Check error tab presence
+       if (indexErrorTab == Index)
+       {
+               // Close the error tab
+               indexErrorTab = -1;
+       }
+       else
+       {
+               // Close source code text tab
+               while ((i < NbSourcesInfos) && strcmp(sourcesinfostab[i++].Filename, t.toLatin1().data()));
+               sourcesinfostab[(i - 1)].IndexTab = -1;
+       }
+
+       // remove the tab
+       sourcestabWidget->removeTab(Index);
+}
+
+
+// 
+void SourcesWindow::keyPressEvent(QKeyEvent * e)
+{
+       // Close/Remove the current tab
+       if (e->key() == Qt::Key_Escape)
+       {
+               CloseCurrentTab();
+       }
+}
+
+
+// 
+void SourcesWindow::Reset(void)
+{
+       // Clear the tabs
+       sourcestabWidget->clear();
+
+       // Clear tab information
+       while (NbSourcesInfos)
+       {
+               free(sourcesinfostab[--NbSourcesInfos].Filename);
+       }
+       free(sourcesinfostab);
+}
+
+
+// 
+void SourcesWindow::Close(void)
+{
+       Reset();
+}
diff --git a/src/debugger/SourcesWin.h b/src/debugger/SourcesWin.h
new file mode 100644 (file)
index 0000000..300c58c
--- /dev/null
@@ -0,0 +1,65 @@
+//
+// SourcesWin.h: Sources tracing window
+//
+// JPM = Jean-Paul Mari <djipi.mari@gmail.com>
+//
+// Who  When        What
+// ---  ----------  -------------------------------------------------------------
+// JPM  08/23/2019  Created this file
+//
+
+#ifndef __SOURCESWIN_H__
+#define __SOURCESWIN_H__
+
+#include <QtWidgets>
+//#include <stdint.h>
+
+class SourceCWindow;
+
+class SourcesWindow : public QWidget
+{
+       Q_OBJECT
+
+       typedef struct S_SOURCESINFOS
+       {
+               int IndexTab;
+               char *Filename;
+               char **SourceText;
+               size_t NbLinesText[2];
+               size_t *NumLinesUsed;
+               size_t Language;
+               SourceCWindow *sourceCtab;
+               int CurrentNumLineSrc;
+       }
+       SourcesInfos;
+
+public:
+       SourcesWindow(QWidget * parent = 0);
+       void Init(void);
+       void Close(void);
+       void Reset(void);
+       bool GetTraceStatus(void);
+       bool CheckChangeLine(void);
+
+public slots:
+       void RefreshContents(void);
+       void SelectTab(const int);
+       void CloseTab(const int);
+
+protected:
+       void keyPressEvent(QKeyEvent * e);
+       void CloseCurrentTab(void);
+
+private:
+       QVBoxLayout *layout;
+       QTabWidget *sourcestabWidget;
+       SourcesInfos *sourcesinfostab;
+       size_t NbSourcesInfos;
+       size_t CurrentTab;
+       size_t OldCurrentNumLineSrc;
+       size_t OldCurrentTab;
+       int indexErrorTab;
+       SourceCWindow *sourceErrorTab;
+};
+
+#endif // __SOURCESWIN_H__
index 98f1df8..ede2dc8 100644 (file)
@@ -23,7 +23,7 @@
 // JPM   Oct./2018  Added search paths in the settings, breakpoints feature, cartridge view menu\r
 // JPM  11/18/2018  Fix crash with non-debugger mode\r
 // JPM  April/2019  Added ELF sections check, added a save memory dump\r
-// JPM   Aug./2019  Update texts descriptions, set cartridge view menu for debugger mode only, added a HW registers browser\r
+// JPM   Aug./2019  Update texts descriptions, set cartridge view menu for debugger mode only, added a HW registers browser and source level tracing\r
 //\r
 \r
 // FIXED:\r
 //\r
 // STILL TO BE DONE:\r
 //\r
+// - The source file listing do not need to be refresh more than one time\r
 // - Fix bug in switching between PAL & NTSC in fullscreen mode.\r
 // - Remove SDL dependencies (sound, mainly) from Jaguar core lib\r
-// - Fix inconsistency with trailing slashes in paths (eeproms needs one,\r
-//   software doesn't)\r
+// - Fix inconsistency with trailing slashes in paths (eeproms needs one, software doesn't)\r
 //\r
 // SFDX CODE: S1E9T8H5M23YS\r
 \r
@@ -91,6 +91,7 @@
 #include "debugger/DBGManager.h"\r
 //#include "debugger/VideoWin.h"\r
 //#include "debugger/DasmWin.h"\r
+#include "debugger/SourcesWin.h"\r
 #include "debugger/m68KDasmWin.h"\r
 #include "debugger/GPUDasmWin.h"\r
 #include "debugger/DSPDasmWin.h"\r
@@ -244,9 +245,11 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false),
 #endif\r
                // Setup disasm tabs\r
                dasmtabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);\r
-               dasmtabWidget->addTab(m68kDasmWin = new m68KDasmWindow(this), tr("M68000"));\r
+               dasmtabWidget->addTab(SourcesWin = new SourcesWindow(this), tr("Sources"));\r
+               dasmtabWidget->setCurrentIndex(dasmtabWidget->addTab(m68kDasmWin = new m68KDasmWindow(this), tr("M68000")));\r
                dasmtabWidget->addTab(GPUDasmWin = new GPUDasmWindow(this), tr("GPU"));\r
                dasmtabWidget->addTab(DSPDasmWin = new DSPDasmWindow(this), tr("DSP"));\r
+               connect(dasmtabWidget, SIGNAL(currentChanged(const int)), this, SLOT(SelectdasmtabWidget(const int)));\r
 #if 1\r
                setCentralWidget(dasmtabWidget);\r
 #endif\r
@@ -858,6 +861,17 @@ void MainWin::SyncUI(void)
 }\r
 \r
 \r
+// \r
+void MainWin::SelectdasmtabWidget(const int Index)\r
+{\r
+       // check sources tab\r
+       if (Index == 0)\r
+       {\r
+               SourcesWin->RefreshContents();\r
+       }\r
+}\r
+\r
+\r
 void MainWin::closeEvent(QCloseEvent * event)\r
 {\r
        JaguarDone();\r
@@ -1480,6 +1494,7 @@ void MainWin::LoadSoftware(QString file)
        {\r
                m68k_set_reg(M68K_REG_A6, 0);\r
                m68kDasmWin->SetAddress(jaguarRunAddress);\r
+               SourcesWin->Init();\r
                //pauseAct->setDisabled(false);\r
                //pauseAct->setChecked(true);\r
                ToggleRunState();\r
@@ -1567,7 +1582,18 @@ void MainWin::ShowSaveDumpAsWin(void)
 // Step Into trace\r
 void MainWin::DebuggerTraceStepInto(void)\r
 {\r
-       JaguarStepInto();\r
+       if (SourcesWin->isVisible() && SourcesWin->GetTraceStatus())\r
+       {\r
+               while (!SourcesWin->CheckChangeLine())\r
+               {\r
+                       JaguarStepInto();\r
+               }\r
+       }\r
+       else\r
+       {\r
+               JaguarStepInto();\r
+       }\r
+\r
        videoWidget->updateGL();\r
        RefreshWindows();\r
 #ifdef _MSC_VER\r
@@ -1587,11 +1613,13 @@ void MainWin::DebuggerRestart(void)
        m68k_set_reg(M68K_REG_PC, jaguarRunAddress);\r
        m68k_set_reg(M68K_REG_SP, vjs.DRAM_size);\r
 #endif\r
+       dasmtabWidget->setCurrentIndex(1);              // set focus on the disasm M68K tab\r
        m68k_set_reg(M68K_REG_A6, 0);\r
        m68k_brk_hitcounts_reset();\r
        bpmHitCounts = 0;\r
        DebuggerResetWindows();\r
        CommonResetWindows();\r
+       SourcesWin->Init();\r
        RefreshWindows();\r
 #ifdef _MSC_VER\r
 #pragma message("Warning: !!! Need to verify the Restart function !!!")\r
@@ -1604,7 +1632,15 @@ void MainWin::DebuggerRestart(void)
 // Step Over trace\r
 void MainWin::DebuggerTraceStepOver(void)\r
 {\r
-       JaguarStepOver(0);\r
+       if (SourcesWin->isVisible() && SourcesWin->GetTraceStatus())\r
+       {\r
+\r
+       }\r
+       else\r
+       {\r
+               JaguarStepOver(0);\r
+       }\r
+\r
        videoWidget->updateGL();\r
        RefreshWindows();\r
 #ifdef _MSC_VER\r
@@ -2423,6 +2459,7 @@ void MainWin::DebuggerResetWindows(void)
                heapallocatorBrowseWin->Reset();\r
                BreakpointsWin->Reset();\r
                CartFilesListWin->Reset();\r
+               SourcesWin->Reset();\r
                //ResetAlpineWindows();\r
        }\r
 }\r
@@ -2456,6 +2493,7 @@ void MainWin::DebuggerRefreshWindows(void)
        if (vjs.softTypeDebugger)\r
        {\r
                FilesrcListWin->RefreshContents();\r
+               SourcesWin->RefreshContents();\r
                m68kDasmWin->RefreshContents();\r
                GPUDasmWin->RefreshContents();\r
                DSPDasmWin->RefreshContents();\r
index 466c2a4..8ac4058 100644 (file)
@@ -36,6 +36,7 @@ class RISCDasmBrowserWindow;
 class HWRegsBrowserWindow;\r
 \r
 // Debugger\r
+class SourcesWindow;\r
 class m68KDasmWindow;\r
 class GPUDasmWindow;\r
 class DSPDasmWindow;\r
@@ -115,6 +116,7 @@ class MainWin: public QMainWindow
                void DeleteAllBreakpoints(void);\r
                void DisableAllBreakpoints(void);\r
                void ShowSaveDumpAsWin(void);\r
+               void SelectdasmtabWidget(const int);\r
 #if 0\r
                void ShowVideoOutputWin(void);\r
                void ShowDasmWin(void);\r
@@ -164,6 +166,7 @@ class MainWin: public QMainWindow
                //DasmWindow * DasmWin;\r
                QTabWidget *dasmtabWidget;\r
                //QDockWidget *dasmtabWidget;\r
+               SourcesWindow *SourcesWin;\r
                m68KDasmWindow *m68kDasmWin;\r
                GPUDasmWindow *GPUDasmWin;\r
                DSPDasmWindow *DSPDasmWin;\r
index 515223c..fa4be73 100644 (file)
@@ -111,6 +111,8 @@ HEADERS = \
        src/debugger/debuggertab.h \\r
        src/debugger/DasmWin.h \\r
        src/debugger/m68kDasmWin.h \\r
+       src/debugger/SourcesWin.h \\r
+       src/debugger/SourceCWin.h \\r
        src/debugger/DBGManager.h \\r
        src/debugger/DSPDasmWin.h \\r
        src/debugger/GPUDasmWin.h \\r
@@ -167,6 +169,8 @@ SOURCES = \
        src/debugger/debuggertab.cpp \\r
        src/debugger/DasmWin.cpp \\r
        src/debugger/m68kDasmWin.cpp \\r
+       src/debugger/SourcesWin.cpp \\r
+       src/debugger/SourceCWin.cpp \\r
        src/debugger/DBGManager.cpp \\r
        src/debugger/DSPDasmWin.cpp \\r
        src/debugger/GPUDasmWin.cpp \\r