home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / monitors / rsys / rsyssrc.lha / RSysMonitor.c < prev    next >
C/C++ Source or Header  |  1993-09-19  |  17KB  |  607 lines

  1. /*
  2. ***************************************************************************
  3. *
  4. * Datei:
  5. *    RSysMonitor.c
  6. *
  7. * Inhalt:
  8. *
  9. *      --- Globale Routinen ---
  10. *
  11. *    void Monitor ( struct objectid *obj );
  12. *
  13. *      --- Lokale  Routinen ---
  14. *
  15. *    static int OpenMemMonitorWindow ( void );
  16. *    static void SetListView ( void );
  17. *    static void ConvertLine ( int type , int offset , char *memline , char *nodeline );
  18. *    static void FreeDisplayMemory ( void );
  19. *    static void ReInitDisplays ( void );
  20. *    static int InitDisplays ( void );
  21. *    static void ReadNextBlock ( void );
  22. *    static void ReadPrevBlock ( void );
  23. *    static int DisplayCYGadClicked ( void );
  24. *    static int SaveCGadClicked ( void );
  25. *    static int ASCIIGadClicked ( void );
  26. *    static int SaveHexGadClicked ( void );
  27. *    static int SaveGadClicked ( void );
  28. *    static int PageBackwardGadClicked ( void );
  29. *    static int PageForwardGadClicked ( void );
  30. *    static int StartAdrGadClicked ( void );
  31. *    static int HandleMemMonitorIDCMP ( void );
  32. *
  33. * Bemerkungen:
  34. *    Speichermonitor von RSys. Wird verwendet, wenn keine
  35. *    Modifikation von Objekten möglich ist.
  36. *
  37. * Erstellungsdatum:
  38. *    29-Jul-93    Rolf Böhme
  39. *
  40. * Änderungen:
  41. *    29-Jul-93    Rolf Böhme    Erstellung
  42. *
  43. ***************************************************************************
  44. */
  45.  
  46. #include "RSys.h"
  47. /*#include "I.c"*/
  48.  
  49. int   MemoryLVGadClicked(void);
  50. int   DisplayCYGadClicked(void);
  51. int   SaveCGadClicked(void);
  52. int   ASCIIGadClicked(void);
  53. int   SaveHexGadClicked(void);
  54. int   SaveGadClicked(void);
  55. int   PageBackwardGadClicked(void);
  56. int   PageForwardGadClicked(void);
  57. int   StartAdrGadClicked(void);
  58.  
  59. static struct Window *MemMonitorWnd = NULL;
  60. static struct Gadget *MemMonitorGList = NULL;
  61. struct IntuiMessage MemMonitorMsg;
  62. static struct Gadget *MemMonitorGadgets[13];
  63. static UWORD MemMonitorLeft = 37;
  64. static UWORD MemMonitorTop = 14;
  65. static UWORD MemMonitorWidth = 616;
  66. static UWORD MemMonitorHeight = 217;
  67. static UBYTE *MemMonitorWdt = (UBYTE *) NAME " - Monitor";
  68.  
  69. static UBYTE *DisplayCYGad0Labels[]=
  70. {
  71.    (UBYTE *) "Hex/ASCII",
  72.    (UBYTE *) "Hex",
  73.    (UBYTE *) "ASCII",
  74.    NULL};
  75.  
  76. static char *headerline[3] =
  77. {
  78.    "     00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF",
  79.    "     00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F",
  80.    "     0123456789ABCDEF"
  81. };
  82.  
  83. static enum displaytypes
  84. {
  85.    DT_hexascii, DT_hex, DT_ascii
  86. };
  87.  
  88. static int CurrentDisplayType = DT_hexascii;
  89. static char  Head[BUFSIZE];
  90.  
  91. static struct List DisplayLists[DISPLAYCOUNT];
  92. static struct Node DisplayNodes[DISPLAYCOUNT][LINECOUNT];
  93.  
  94. static union
  95. {
  96.    char  memblock[BLOCKSIZE];
  97.    char  memparts[LINECOUNT][LINESIZE];
  98.    ULONG memlongs[LINECOUNT][LINESIZE / sizeof(ULONG)];
  99. }     MemoryBlock;
  100.  
  101. static ULONG CurrentAddress,
  102.       FirstAddress;
  103.  
  104. static struct Remember *MonKey = NULL;
  105.  
  106. static UWORD MemMonitorGTypes[]=
  107. {
  108.    LISTVIEW_KIND,
  109.    CYCLE_KIND,
  110.    BUTTON_KIND,
  111.    BUTTON_KIND,
  112.    BUTTON_KIND,
  113.    BUTTON_KIND,
  114.    BUTTON_KIND,
  115.    BUTTON_KIND,
  116.    TEXT_KIND,
  117.    TEXT_KIND,
  118.    BUTTON_KIND,
  119.     TEXT_KIND,
  120.     TEXT_KIND
  121. };
  122.  
  123. static struct NewGadget MemMonitorNGad[]=
  124. {
  125.    12, 50, 589, 136, NULL, NULL, GD_MemoryLVGad, 0, NULL, NULL,
  126.    476, 19, 125, 13, (UBYTE *) "Display", NULL, GD_DisplayCYGad, PLACETEXT_LEFT, NULL, (APTR) DisplayCYGadClicked,
  127.    12, 201, 142, 13, (UBYTE *) "Save C-Code", NULL, GD_SaveCGad, PLACETEXT_IN, NULL, (APTR) SaveCGadClicked,
  128.    161, 201, 142, 13, (UBYTE *) "Save ASCII", NULL, GD_ASCIIGad, PLACETEXT_IN, NULL, (APTR) ASCIIGadClicked,
  129.    310, 201, 142, 13, (UBYTE *) "Save Hex", NULL, GD_SaveHexGad, PLACETEXT_IN, NULL, (APTR) SaveHexGadClicked,
  130.    459, 201, 142, 13, (UBYTE *) "Save as is", NULL, GD_SaveAsIsGad, PLACETEXT_IN, NULL, (APTR) SaveGadClicked,
  131.    12, 186, 193, 13, (UBYTE *) "<<< Prev 512 Bytes", NULL, GD_PageBackwardGad, PLACETEXT_IN, NULL, (APTR) PageBackwardGadClicked,
  132.    408, 186, 193, 13, (UBYTE *) "Next 512 Bytes >>>", NULL, GD_PageForwardGad, PLACETEXT_IN, NULL, (APTR) PageForwardGadClicked,
  133.    232, 19, 89, 13, (UBYTE *) "Current", NULL, GD_AddressTGad, PLACETEXT_LEFT, NULL, NULL,
  134.    64, 19, 89, 13, (UBYTE *) "Start", NULL, GD_StartAdrTGad, PLACETEXT_LEFT, NULL, NULL,
  135.    210, 186, 193, 13, (UBYTE *) "To start address", NULL, GD_StartAdrGad, PLACETEXT_IN, NULL, (APTR) StartAdrGadClicked,
  136.     64, 4, 537, 13, (UBYTE *)"Entry", NULL, GD_EntryInfo, PLACETEXT_LEFT, NULL, NULL,
  137.     12, 36, 589, 13, (UBYTE *)NULL, NULL, GD_HeaderLine, PLACETEXT_LEFT, NULL, NULL
  138. };
  139.  
  140. static ULONG *MemMonitorGTags[]=
  141. {
  142.    (ULONG *) (GTLV_ReadOnly), (ULONG *) TRUE, (ULONG *) (TAG_DONE),
  143.    (ULONG *) (GTCY_Labels), (ULONG *) & DisplayCYGad0Labels[0], (ULONG *) (TAG_DONE),
  144.    (ULONG *) (TAG_DONE),
  145.    (ULONG *) (TAG_DONE),
  146.    (ULONG *) (TAG_DONE),
  147.    (ULONG *) (TAG_DONE),
  148.    (ULONG *) (TAG_DONE),
  149.    (ULONG *) (TAG_DONE),
  150.    (ULONG *) (GTTX_Border), (ULONG *) TRUE, (ULONG *) (TAG_DONE),
  151.    (ULONG *) (GTTX_Border), (ULONG *) TRUE, (ULONG *) (TAG_DONE),
  152.    (ULONG *) (TAG_DONE),
  153.     (ULONG *) (GTTX_Border), (ULONG *)TRUE, (ULONG *)(TAG_DONE),
  154.     (ULONG *) (GTTX_Border), (ULONG *)TRUE, (ULONG *)(TAG_DONE),
  155. };
  156.  
  157. static int
  158. OpenMemMonitorWindow(void)
  159. {
  160.    struct NewGadget ng;
  161.    struct Gadget *g;
  162.    UWORD lc,
  163.          tc;
  164.    UWORD wleft = MemMonitorLeft,
  165.          wtop = MemMonitorTop,
  166.          ww,
  167.          wh;
  168.    int   gl[]=
  169.    {GD_MemoryLVGad-GD_MemoryLVGad, GD_AddressTGad-GD_MemoryLVGad,
  170.     GD_StartAdrTGad-GD_MemoryLVGad, GD_EntryInfo-GD_MemoryLVGad,
  171.     GD_HeaderLine-GD_MemoryLVGad};
  172.  
  173.    AdjustWindowDimensions(Scr, MemMonitorLeft, MemMonitorTop,
  174.                           MemMonitorWidth, MemMonitorHeight,
  175.                           &wleft, &wtop, &ww, &wh);
  176.  
  177.    if (!(g = CreateContext(&MemMonitorGList)))
  178.       return (1L);
  179.  
  180.    for (lc = 0, tc = 0; lc < MemMonitor_CNT; lc++)
  181.    {
  182.  
  183.       CopyMem((char *)&MemMonitorNGad[lc], (char *)&ng, (long)sizeof(struct NewGadget));
  184.  
  185.       ng.ng_VisualInfo = VisualInfo;
  186.       ng.ng_TextAttr = Font;
  187.       ng.ng_LeftEdge = OffX + ComputeX(ng.ng_LeftEdge);
  188.       ng.ng_TopEdge = OffY + ComputeY(ng.ng_TopEdge);
  189.       ng.ng_Width = ComputeX(ng.ng_Width);
  190.       ng.ng_Height = ComputeY(ng.ng_Height);
  191.  
  192.       MemMonitorGadgets[lc] = g = CreateGadgetA((ULONG) MemMonitorGTypes[lc], g, &ng, (struct TagItem *) & MemMonitorGTags[tc]);
  193.  
  194.       while (MemMonitorGTags[tc])
  195.          tc += 2;
  196.       tc++;
  197.  
  198.       if (NOT g)
  199.          return (2L);
  200.    }
  201.  
  202.    if (!(MemMonitorWnd = OpenWindowTags(NULL,
  203.                                         WA_Left, wleft,
  204.                                         WA_Top, wtop,
  205.                                         WA_Width, ww,
  206.                                         WA_Height, wh,
  207.                                         WA_IDCMP, LISTVIEWIDCMP |
  208.                                         CYCLEIDCMP | BUTTONIDCMP |
  209.                                         TEXTIDCMP | IDCMP_CLOSEWINDOW |
  210.                                         IDCMP_REFRESHWINDOW |
  211.                                         IDCMP_VANILLAKEY,
  212.                                         WA_Flags, WFLG_DRAGBAR |
  213.                                         WFLG_DEPTHGADGET |
  214.                                         WFLG_CLOSEGADGET |
  215.                                         WFLG_SMART_REFRESH |
  216.                                         WFLG_RMBTRAP,
  217.                                         WA_Title, MemMonitorWdt,
  218.                                         WA_PubScreenFallBack, TRUE,
  219.                                         WA_PubScreen, Scr,
  220.                                         TAG_DONE)))
  221.       return (4L);
  222.  
  223.    RefreshRastPort(MemMonitorWnd, MemMonitorGadgets, gl, 5, FALSE, MemMonitorGList);
  224.  
  225.    return (0L);
  226. }
  227.  
  228. static void
  229. SetTextGadgets(void)
  230. {
  231.    char curraddr[10], addr[10];
  232.  
  233.    sprintf(curraddr,"%08lx", CurrentAddress);
  234.    sprintf(addr,"%08lx", FirstAddress);
  235.  
  236.     GT_SetGadgetAttrs(MemMonitorGadgets[GD_AddressTGad-GD_MemoryLVGad], MemMonitorWnd,
  237.                             NULL,
  238.                             GTTX_Text, (UBYTE *) curraddr,
  239.                             TAG_DONE);
  240.  
  241.     GT_SetGadgetAttrs(MemMonitorGadgets[GD_StartAdrTGad-GD_MemoryLVGad], MemMonitorWnd,
  242.                             NULL,
  243.                             GTTX_Text, (UBYTE *) addr,
  244.                             TAG_DONE);
  245.  
  246.     GT_SetGadgetAttrs(MemMonitorGadgets[GD_HeaderLine-GD_MemoryLVGad], MemMonitorWnd,
  247.                             NULL,
  248.                             GTTX_Text, (UBYTE *) headerline[CurrentDisplayType],
  249.                             TAG_DONE);
  250.  
  251.    return;
  252. }
  253.  
  254. static void
  255. SetListView(void)
  256. {
  257.    InitListView(MemMonitorWnd, MemMonitorGadgets[GD_MemoryLVGad-GD_MemoryLVGad],
  258.                 &DisplayLists[CurrentDisplayType], UNSETLVPOS);
  259.  
  260.    return;
  261. }
  262.  
  263. static void
  264. ConvertLine(int type, int offset, char *memline, char *nodeline)
  265. {
  266.    char  bytehex[LINESIZE][4],
  267.          i,
  268.          offsetstr[7],
  269.          charline[LINESIZE + 1];
  270.  
  271.    for (i = 0; i < LINESIZE; i++)
  272.    {
  273.       sprintf(bytehex[i], "%02lx ", (unsigned char)memline[i]);
  274.       charline[i] = (isprint((int)memline[i]) ? memline[i] : '.');
  275.    }
  276.  
  277.    charline[LINESIZE] = STRINGEND;
  278.  
  279.    sprintf(offsetstr, "%03lx: ", offset*16);
  280.  
  281.    switch (type)
  282.    {
  283.       case DT_hexascii:
  284.          strncpy(nodeline, offsetstr, 5);
  285.          for (i = 0; i < LINESIZE; i++) strncat(nodeline, bytehex[i], 4);
  286.          strncat(nodeline, charline, LINESIZE);
  287.          break;
  288.  
  289.       case DT_hex:
  290.          strncpy(nodeline, offsetstr, 5);
  291.          for (i = 0; i < LINESIZE; i++) strncat(nodeline, bytehex[i], 4);
  292.          break;
  293.  
  294.       case DT_ascii:
  295.          strncpy(nodeline, offsetstr, 5);
  296.          strncat(nodeline, charline, LINESIZE);
  297.          break;
  298.    }
  299.  
  300.    return;
  301. }
  302.  
  303. static void
  304. FreeDisplayMemory(void)
  305. {
  306.    FreeRemember(MONKEY, TRUE);
  307.    return;
  308. }
  309.  
  310. static void
  311. ReInitDisplays(void)
  312. {
  313.    char  memline[LINESIZE + 1];
  314.    char  displaytype,
  315.          j;
  316.  
  317.    SetTextGadgets();
  318.  
  319.    Forbid();
  320.    CopyMem((APTR) CurrentAddress, (APTR) & MemoryBlock, BLOCKSIZE);
  321.    Permit();
  322.  
  323.    for (displaytype = 0; displaytype < DISPLAYCOUNT; displaytype++)
  324.    {
  325.       NewList(&DisplayLists[displaytype]);
  326.  
  327.       for (j = 0; j < LINECOUNT; j++)
  328.       {
  329.          CopyMem(&MemoryBlock.memparts[j][0], &memline[0], LINESIZE);
  330.  
  331.          ConvertLine((int)displaytype, (int)j, memline, DisplayNodes[displaytype][j].ln_Name);
  332.  
  333.          AddTail(&DisplayLists[displaytype], &DisplayNodes[displaytype][j]);
  334.       }
  335.    }
  336.  
  337.    SetListView();
  338.  
  339.    return;
  340. }
  341.  
  342. static int
  343. InitDisplays(void)
  344. {
  345.    char  memline[LINESIZE + 1];
  346.    char  displaytype,
  347.          j;
  348.  
  349.    SetTextGadgets();
  350.  
  351.    Forbid();
  352.    CopyMem((APTR) CurrentAddress, (APTR) & MemoryBlock, BLOCKSIZE);
  353.    Permit();
  354.  
  355.    for (displaytype = 0; displaytype < DISPLAYCOUNT; displaytype++)
  356.    {
  357.       NewList(&DisplayLists[displaytype]);
  358.  
  359.       for (j = 0; j < LINECOUNT; j++)
  360.       {
  361.          DisplayNodes[displaytype][j].ln_Name = AllocMonMem(3 * (LINESIZE + 9));
  362.  
  363.          if (!DisplayNodes[displaytype][j].ln_Name) return FALSE;
  364.  
  365.          DisplayNodes[displaytype][j].ln_Type = NT_USER;
  366.          DisplayNodes[displaytype][j].ln_Pri = 0;
  367.  
  368.          CopyMem(&MemoryBlock.memparts[j][0], &memline[0], LINESIZE);
  369.  
  370.          ConvertLine((int)displaytype, (int)j, memline, DisplayNodes[displaytype][j].ln_Name);
  371.  
  372.          AddTail(&DisplayLists[displaytype], &DisplayNodes[displaytype][j]);
  373.       }
  374.    }
  375.  
  376.    SetListView();
  377.  
  378.    return TRUE;
  379. }
  380.  
  381. static void
  382. ReadNextBlock(void)
  383. {
  384.    if (CurrentAddress + 512L <= 0x01000000L) CurrentAddress += 512L;
  385.    ReInitDisplays();
  386.  
  387.    return;
  388. }
  389.  
  390. static void
  391. ReadPrevBlock(void)
  392. {
  393.    if (CurrentAddress - 512 >= 0) CurrentAddress -= 512L;
  394.    ReInitDisplays();
  395.  
  396.    return;
  397. }
  398.  
  399. static int
  400. DisplayCYGadClicked(void)
  401. {
  402.    CurrentDisplayType = MemMonitorMsg.Code;
  403.    SetListView();
  404.  
  405.    return TRUE;
  406. }
  407.  
  408. static int
  409. SaveCGadClicked(void)
  410. {
  411.    /* routine when gadget "Save C-Code" is clicked. */
  412.    BPTR fout;
  413.    int i;
  414.  
  415.    sprintf(Head, "/\*\n   RSys-C-Code Generator"
  416.                  "\n   Memory at 0x%08lx\n\*/\n\n", CurrentAddress);
  417.  
  418.    if (GetFile(MemMonitorWnd, "T:", "RSysData.c", "#?.c", "Save C-Code...", "Save"))
  419.    {
  420.       fout = AskFileMode((char *)_fullpath, MemMonitorWnd);
  421.  
  422.       if(fout)
  423.       {
  424.          FPuts(fout, (STRPTR)Head);
  425.          FPuts(fout, (STRPTR)"ULONG RSysData[] = \{\n");
  426.  
  427.          for(i = 0; i < LINECOUNT; i++)
  428.             FPrintf(fout, (STRPTR)"   0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx,\n",
  429.                     MemoryBlock.memlongs[i][0],
  430.                     MemoryBlock.memlongs[i][1],
  431.                     MemoryBlock.memlongs[i][2],
  432.                     MemoryBlock.memlongs[i][3]);
  433.  
  434.          FPuts(fout, (STRPTR)"\};\n/\* End of Code \*/\n" );
  435.  
  436.          Close(fout);
  437.       }
  438.    }
  439.  
  440.    return TRUE;
  441. }
  442.  
  443. static int
  444. ASCIIGadClicked(void)
  445. {
  446.    /* routine when gadget "Save ASCII" is clicked. */
  447.    sprintf(Head, "Memory at 0x%08lx", CurrentAddress);
  448.  
  449.    if (GetFile(MemMonitorWnd, "T:", "RSysMemoryASCII.dat", "#?.dat",
  450.                "Save as ASCII-Data...", "Save"))
  451.       SaveList(MemMonitorWnd, (char *)_fullpath, Head,
  452.                &DisplayLists[DT_ascii], FALSE);
  453.  
  454.    return TRUE;
  455. }
  456.  
  457. static int
  458. SaveHexGadClicked(void)
  459. {
  460.    /* routine when gadget "Save Hex" is clicked. */
  461.  
  462.    sprintf(Head, "Memory at 0x%08lx", CurrentAddress);
  463.  
  464.    if (GetFile(MemMonitorWnd, "T:", "RSysMemoryHEX.dat", "#?.dat",
  465.                "Save as Hex-Datas...", "Save"))
  466.       SaveList(MemMonitorWnd, (char *)_fullpath, Head,
  467.                &DisplayLists[DT_hex], FALSE);
  468.    return TRUE;
  469. }
  470.  
  471. static int
  472. SaveGadClicked(void)
  473. {
  474.    /* routine when gadget "Save as is" is clicked. */
  475.  
  476.    sprintf(Head, "Memory at 0x%08lx", CurrentAddress);
  477.  
  478.    if (GetFile(MemMonitorWnd, "T:", "MemoryList.dat", "#?.dat",
  479.                "Save List as is...", "Save"))
  480.       SaveList(MemMonitorWnd, (char *)_fullpath, Head,
  481.                &DisplayLists[CurrentDisplayType], FALSE);
  482.  
  483.    return TRUE;
  484. }
  485.  
  486. static int
  487. PageBackwardGadClicked(void)
  488. {
  489.    /* routine when gadget "<<< Prev 512 Bytes" is clicked. */
  490.    ReadPrevBlock();
  491.  
  492.    return TRUE;
  493. }
  494.  
  495. static int
  496. PageForwardGadClicked(void)
  497. {
  498.    /* routine when gadget "Next 512 Bytes >>>" is clicked. */
  499.    ReadNextBlock();
  500.  
  501.    return TRUE;
  502. }
  503.  
  504. static int
  505. StartAdrGadClicked(void)
  506. {
  507.    CurrentAddress = FirstAddress;
  508.  
  509.    ReInitDisplays();
  510.  
  511.    return TRUE;
  512. }
  513.  
  514. static int
  515. HandleMemMonitorIDCMP(void)
  516. {
  517.    struct IntuiMessage *m;
  518.    int   (*func) (void);
  519.    BOOL  running = TRUE;
  520.  
  521.    while (m = GT_GetIMsg(MemMonitorWnd->UserPort))
  522.    {
  523.       CopyMem((char *)m, (char *)&MemMonitorMsg, (long)sizeof(struct IntuiMessage));
  524.  
  525.       GT_ReplyIMsg(m);
  526.  
  527.       switch (MemMonitorMsg.Class)
  528.       {
  529.          case IDCMP_REFRESHWINDOW:
  530.             MakeWindowRefresh(MemMonitorWnd);
  531.             break;
  532.  
  533.          case IDCMP_CLOSEWINDOW:
  534.             running = FALSE;
  535.             break;
  536.  
  537.          case IDCMP_VANILLAKEY:
  538.                if (MemMonitorMsg.Code == ESC) running = FALSE;
  539.             break;
  540.  
  541.          case IDCMP_GADGETUP:
  542.          case IDCMP_GADGETDOWN:
  543.             HandleHelp(((struct Gadget *)MemMonitorMsg.IAddress)->GadgetID);
  544.             func = (void *)((struct Gadget *) MemMonitorMsg.IAddress)->UserData;
  545.             running = func();
  546.             break;
  547.       }
  548.    }
  549.    return (running);
  550. }
  551.  
  552. void
  553. Monitor(struct objectid *obj, char *entrystring)
  554. {
  555.    ValidMemoryNode *vmnode;
  556.    char header[2*BUFSIZE];
  557.  
  558.    HandleHelp(MONITOR);
  559.  
  560.    CurrentDisplayType = DT_hexascii;
  561.  
  562.    CurrentAddress = (ULONG)obj->address;
  563.    FirstAddress = (ULONG)obj->address;
  564.  
  565.    vmnode = CheckNode(CurrentAddress);
  566.  
  567.    if(!vmnode) ErrorHandle("Address not found in table", MEMORY_ERR, TYPE_FAIL, NO_KILL);
  568.    else
  569.       if(!IsValid(vmnode) && !MyEasyRequest(SysWnd,(STRPTR)NAME " - Memory validation info",
  570.                              (STRPTR)"Call Monitor|Cancel",
  571.                              (STRPTR)"You requested a memory start address which is not valid\n"
  572.                                      "and can produce an Enforcer Hit! The Attributes are:\n"
  573.                                      "%s \n%s \n%s\nComment: %s\n"
  574.                                      "Do you want to call the " NAME "-Monitor anyway?",
  575.                                      "- Invalid",
  576.                                      (IsWriteProtect(vmnode) ? "- Write protected" : "- Not write protected"),
  577.                                      (IsCacheable(vmnode) ? "- Cacheable" : "- Not cacheable"),
  578.                                      vmnode->vm_comment))
  579.          return;
  580.  
  581.    if (OpenASysWindow(OpenMemMonitorWindow, NO_KILL))
  582.    {
  583.       LockMainWindow(LOCK);
  584.  
  585.       if(vmnode) sprintf(header,"%s [%s]", &entrystring[9], vmnode->vm_comment);
  586.       else
  587.          sprintf(header,"%s [no valid memory info]", &entrystring[9]);
  588.  
  589.        GT_SetGadgetAttrs(MemMonitorGadgets[GD_EntryInfo-GD_MemoryLVGad], MemMonitorWnd,
  590.                                NULL,
  591.                                GTTX_Text, (UBYTE *) header,
  592.                                TAG_DONE);
  593.  
  594.       if (InitDisplays()) while (HandleMemMonitorIDCMP()) ;
  595.       else
  596.          ErrorHandle("Display nodes", MEMORY_ERR, ALLOC_FAIL, NO_KILL);
  597.  
  598.       FreeDisplayMemory();
  599.  
  600.       CloseASysWindow(&MemMonitorWnd, &MemMonitorGList, NULL);
  601.  
  602.       LockMainWindow(UNLOCK);
  603.    }
  604.  
  605.    return;
  606. }
  607.