home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / SCROLLA.C < prev    next >
Text File  |  1996-03-12  |  54KB  |  949 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   scrolla.c                                                               */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*                                                                           */
  7. /*  Handle scrolling in the disassembly view.                                */
  8. /*                                                                           */
  9. /* History:                                                                  */
  10. /*                                                                           */
  11. /*   08/30/91 Creation of 32-bit SD86, from 16-bit version.                  */
  12. /*            Extracted from showa.c and rewritten.                          */
  13. /*                                                                           */
  14. /*...Release 1.00 (Pre-release 1)                                            */
  15. /*...                                                                        */
  16. /*... 08/30/91  235   Joe       Cleanup/rewrite ascroll() to fix several bugs*/
  17. /*...                                                                        */
  18. /*...Release 1.00 (Pre-release 107 11/13/91)                                 */
  19. /*...                                                                        */
  20. /*... 11/13/91  400   Srinivas  Vertical Register Display.                   */
  21. /*...                                                                        */
  22. /*... 11/18/91  401   Srinivas  Floating point Register Display.             */
  23. /*...                                                                        */
  24. /*... 11/21/91  402   Joe       Fix source/disassembly synchronization.      */
  25. /*...                                                                        */
  26. /*... 11/21/91  404   Joe       S_f3 in MIXED disasm view with all src lines */
  27. /*...                           hangs.                                       */
  28. /*...                                                                        */
  29. /*...Release 1.00 (Pre-release 108 12/05/91)                                 */
  30. /*...                                                                        */
  31. /*... 02/11/92  518   Srinivas  Remove limitation on max no of screen rows.  */
  32. /*... 02/11/92  519   Srinivas  Zoomrec Sizing Problems.                     */
  33. /*... 02/12/92  521   Srinivas  Port to C-Set/2.                             */
  34. /*... 02/14/92  530   Srinivas  Jumping across ID in case of PLX disassembly */
  35. /*...                                                                        */
  36. /*...Release 1.00 (03/03/92)                                                 */
  37. /*...                                                                        */
  38. /*... 03/18/92  606   Srinivas  Handle multiple segment numbers in lno table */
  39. /*...                           due to alloc_text pragma.                    */
  40. /*... 12/14/93  911   Joe       Hang showing PL/X disassembly of select stmt.*/
  41. /**Includes*******************************************************************/
  42.                                         /*                                   */
  43. #include "all.h"                        /* SD86 include files                */
  44. static int iview=0;                     /*                                   */
  45. /**Macros ********************************************************************/
  46.                                         /*                                   */
  47. #define N1KEYS 29                       /*                                   */
  48. #define ENDOFTABLE 0xFFFFFFFF           /* marker for end of display table521*/
  49.  
  50. #define ATTR_BKPT_OK_LINE      Attrib(vaBptOk)  /* line ok for brkpt.        */
  51. #define ATTR_BKPT_ON_LINE      Attrib(vaBptOn)  /* bkpt on this line.        */
  52. #define ATTR_EXEC_LINE         Attrib(vaXline)  /* executing line.           */
  53. #define ATTR_BKPT_ON_EXEC_LINE Attrib(vaXlineOn)/* brkpt on executing line.  */
  54. #define ATTR_SOURCE_LINE       Attrib(vaMxdSrc) /* source line color.        */
  55.  
  56. /**External declararions******************************************************/
  57.                                         /*                                   */
  58. extern uint   VideoCols;                /*                                   */
  59. extern uint   VideoRows;                /*                                   */
  60. extern uint   NActFrames;               /*                                   */
  61. extern uchar *ActFaddrs[];              /*                                   */
  62. extern uint   RowsUsed;                 /*                                   */
  63. extern int    AsmTop;                   /*                                   */
  64. extern uchar  Reg_Display;              /*                                400*/
  65. extern PROCESS_NODE *pnode;                                             /*827*/
  66.                                         /*                                   */
  67. /**External definitions*******************************************************/
  68.                                         /*                                   */
  69. uint   *AddrCache;                      /*                                518*/
  70. uint   *SourceLineCache;                /*                                518*/
  71. static uint   *TempAddrCache;           /*                                518*/
  72. static uint   *TempSourceLineCache;     /*                                518*/
  73. static uint   AsmTableSize;             /* disassembly table size         518*/
  74. static uchar  *textbuf;                 /* -> to disasembly text          518*/
  75. static uint   TextBufSize;              /* length of disassembly text buf 518*/
  76. int     AsmRows;                        /*                                   */
  77. INSTR  *icache;                         /*                                   */
  78. int     CacheAnchorIndex;               /*                                   */
  79. int     InstrCacheSize;                 /*                                   */
  80.  
  81. extern  int iview;
  82. /**Begin Code*****************************************************************/
  83.                                         /*                                   */
  84. /*****************************************************************************/
  85. /* ascroll()                                                                 */
  86. /*                                                                           */
  87. /* Description:                                                              */
  88. /*   display the assembler window.                                           */
  89. /*                                                                           */
  90. /* Parameters:                                                               */
  91. /*                                                                           */
  92. /*   fp        input - afile for this asm window.                            */
  93. /*   delta     input - how much to adjust this window.                       */
  94. /*                                                                           */
  95. /* Return:                                                                   */
  96. /*                                                                           */
  97. /*   seekline  ?????????????????????????????????                             */
  98. /*                                                                           */
  99. /* Assumptions:                                                              */
  100. /*                                                                           */
  101. /*   none.                                                                   */
  102. /*                                                                           */
  103. /*****************************************************************************/
  104.                                         /*                                   */
  105.   uint                                  /*                                   */
  106. ascroll(AFILE *fp, int  delta )         /*                                   */
  107. {                                       /*                                   */
  108.  uint      n;                           /* assembler text buffer index.      */
  109.  uint      lno;                         /* a source line number.             */
  110.  uchar    *cp;                          /* -> into disassembled text buffer. */
  111.  uchar     digits[6];                   /* buffer for lno ascii digits.      */
  112.  uint      i;                           /* just an i.                        */
  113.  uint      ndigits;                     /* # of digits converted by buffmt.  */
  114.  uint      brkxline;                    /* line # of brkpt & exec line.      */
  115.  uint      addr; /* !!! */              /* an address.                       */
  116.  uchar    *ptr;                         /* a ptr.                            */
  117.   int     row;                          /* was uint              !!!     235 */
  118.   uint    span;                         /*                                   */
  119.   uint    count;                        /*                                   */
  120.   uint    read;                         /*                                   */
  121.    int index;
  122.  
  123.    int   TopMargin;
  124.    ULONG  StartLineNumber;              /* changed to uint                521*/
  125.    uint   junk;                         /* changed to uint                521*/
  126.    uint  StartAddr;
  127.    int   TableDone;
  128.    int   LastIndex;
  129.    int   idx;
  130.    uint FirstAddrForLine;
  131.  
  132.  
  133.  if( icache == NULL )
  134.  {
  135.   int size;
  136.   InstrCacheSize = 4*(VideoRows - 2);   /* removed regrows                400*/
  137.   CacheAnchorIndex = InstrCacheSize/2;
  138.   size = (InstrCacheSize + 1)*sizeof(INSTR);
  139.   icache = ( INSTR *)Talloc( size );                                    /*521*/
  140.  
  141.   /***************************************************************************/
  142.   /* Allocate memory for the arrays depending on the number of videorows. 518*/
  143.   /* Removed array declarations and added dynamic allocation.             518*/
  144.   /*                                                                      518*/
  145.   /* Note :                                                               518*/
  146.   /*   - AsmTableSize is equal to VideoRows minus two status lines at     518*/
  147.   /*     the bottom of the screen plus one entry for end of table.        518*/
  148.   /***************************************************************************/
  149.   AsmTableSize         =  (VideoRows - 1) * sizeof(int);                /*518*/                /*518*/
  150.   TempAddrCache        =  (uint *)Talloc( AsmTableSize );           /*521 518*/
  151.   TempSourceLineCache  =  (uint *)Talloc( AsmTableSize );           /*521 518*/
  152.   AddrCache            =  (uint *)Talloc( AsmTableSize );           /*521 518*/
  153.   SourceLineCache      =  (uint *)Talloc( AsmTableSize );           /*521 518*/
  154.   SourceLineCache[0]   =  ENDOFTABLE;                                   /*518*/
  155.  
  156.  
  157.   /***************************************************************************/
  158.   /* Allocate memory for the dis assembly text.                           518*/
  159.   /***************************************************************************/
  160.   TextBufSize = (VideoRows - 2) * (VideoCols+2);                                   /*518*/
  161.   textbuf = (uchar *) Talloc( TextBufSize );                        /*521 518*/
  162.  
  163.  }
  164.  
  165.  if( fp->source == NULL || fp->sview == NOSRC )
  166.  {
  167.   /** First, we'll handle views without source *******************************/
  168.   /*                                                                         */
  169.   /* We come into ascroll() with a delta value that tells us how far to      */
  170.   /* move up or down in the disassembly view.  What we will do is define a   */
  171.   /* StartAddr that we will use to build a set of display tables.  The       */
  172.   /* tables will be kept in static storage because we'll need them for       */
  173.   /* some history.                                                           */
  174.   /*                                                                         */
  175.   /* - delta < 0 ==> moving up...pgup,cursor up, etc.                        */
  176.   /* - delta > 0 ==> moving dn...pgdn,cursor dn, etc.                        */
  177.   /* - delta = 0 ==> coming if from mixed source/asm view or refreshing.     */
  178.   /*                                                                         */
  179.   /* delta = 0                                                               */
  180.   /*                                                                         */
  181.   /*   ToggleAsmVIew, i.e.  switching to asm view from mixed view.           */
  182.   /*   The AF_SYNC flag will be set.  We take the current topoff and         */
  183.   /*   expand from there. If there is no topoff, say for a mixed view        */
  184.   /*   showing all comment lines, then don't do anything.                    */
  185.   /*                                                                         */
  186.   /* - Single Step, Go, etc., in which case AF_ZOOM will be set.             */
  187.   /*   If the hotaddr is already on the display, then don't rebuild          */
  188.   /*   the tables, else move the hotaddr to the top of the display.          */
  189.   /*                                                                         */
  190.   /*                                                                         */
  191.   /* delta < 0                                                               */
  192.   /*                                                                         */
  193.   /*  In this case, we make a special call to DBDisa that lets us back up    */
  194.   /*  in the disassembly view.                                               */
  195.   /*                                                                         */
  196.   /* delta > 0                                                               */
  197.   /*                                                                         */
  198.   /*  This is the easy one.  All we have to do is get the StartAddr and      */
  199.   /*  from the last entries in the current display buffers and then          */
  200.   /*  expand down from there.                                                */
  201.   /*                                                                         */
  202.   /***************************************************************************/
  203.   if( delta <= 0 )
  204.   {
  205.    if( delta == 0 )
  206.    {
  207.     if( fp->flags & AF_ZOOM )
  208.     {
  209.      if( IsOnAsmCRT(fp->hotaddr ) )
  210.       goto BUILDTEXT;
  211.  
  212.      StartAddr = fp->topoff;
  213.     }
  214.  
  215.     else if( fp->flags & ASM_VIEW_NEW )
  216.       StartAddr = fp->topoff;
  217.  
  218.     else if( fp->flags & ASM_VIEW_TOGGLE )
  219.     {
  220.      StartAddr = fp->topoff;
  221.      if( StartAddr == NULL )                                            /*404*/
  222.       return( 0);                                                       /*404*/
  223.     }
  224.     else if( fp->flags & ASM_VIEW_CHANGE )
  225.       StartAddr = fp->topoff;
  226.  
  227.     else if( fp->flags & ASM_VIEW_NEXT )
  228.     {
  229.      StartAddr = fp->AsmView.StartAddr;
  230.      goto REBUILDTABLE;
  231.     }
  232.     else if( fp->flags & ASM_VIEW_MNE  )
  233.     {
  234.       DBDisa(fp->mid, 0, 0, 0 );
  235.       goto BUILDTEXT;
  236.     }
  237.     else if( fp->flags & ASM_VIEW_REFRESH )
  238.     {
  239.      goto BUILDTEXT;
  240.     }
  241.    }
  242.  
  243.    else if( delta < 0 )
  244.    {
  245.     /*************************************************************************/
  246.     /* At this point, we have to back up in the disassembly view.            */
  247.     /*************************************************************************/
  248.     index = DBDisa(fp->mid, AddrCache[0], AsmRows, delta );
  249.     StartAddr = icache[index].instaddr;
  250.    }
  251.   }
  252.  
  253.   else if( delta > 0 )
  254.   {
  255.    StartAddr = AddrCache[delta];
  256.   }
  257.  
  258. REBUILDTABLE:
  259.   /***************************************************************************/
  260.   /* Now, we have a StartAddr to begin generating dispaly tables.            */
  261.   /* The display tables will look like so:                                   */
  262.   /*                                                                         */
  263.   /*   SourceLineNumber        AddrCache                                     */
  264.   /*        0                     addr1                                      */
  265.   /*        0                     .                                          */
  266.   /*        0                     .                                          */
  267.   /*        0                     .                                          */
  268.   /*        0                     addri                                      */
  269.   /*        0                     addrj                                      */
  270.   /*        0                     addrk                                      */
  271.   /*        0                     .                                          */
  272.   /*        0                     .                                          */
  273.   /*        0                     .                                          */
  274.   /*        -1 ( ENDOFTABLE )     .                                          */
  275.   /*                                                                         */
  276.   /***************************************************************************/
  277.   TableDone = FALSE;
  278.   addr  = StartAddr;
  279.   memset( TempSourceLineCache, 0 , AsmTableSize );                      /*518*/
  280.   memset( TempAddrCache , 0 , AsmTableSize );                           /*518*/
  281.   index  = DBDisa(fp->mid, StartAddr , AsmRows, 0 );
  282.   LastIndex = AsmRows - 1;
  283.   for ( row = 0 ; row <= LastIndex && TableDone == FALSE; index++,row++ )
  284.   {
  285.    addr = icache[index].instaddr;
  286.    if( addr == ENDOFCACHE )
  287.    {
  288.     TableDone = TRUE;
  289.     break;
  290.    }
  291.    TempAddrCache[row] = addr;
  292.   }
  293.  
  294.   /***************************************************************************/
  295.   /* On a pgdn or cursor down we want to anchor the bottom line to the       */
  296.   /* bottom of the display. So, we check to see if the display table is      */
  297.   /* full, and if not, we make an adjustment and go back and fill it up.     */
  298.   /*                                                                         */
  299.   /* - so, mark the end of the table.                                        */
  300.   /* - check to see if we have a full display.                               */
  301.   /* - if we don't then adjust delta and redo the table.                     */
  302.   /* - if all is ok, then copy the temp tables to the static tables.         */
  303.   /***************************************************************************/
  304.   TempSourceLineCache[row] = ENDOFTABLE;
  305.   for( row=0; TempSourceLineCache[row] != ENDOFTABLE; row++ ){;}
  306.   if( delta > 0 && row < AsmRows )
  307.   {
  308.    delta -= AsmRows - row;
  309.    if( delta < 0 )
  310.     delta = 0;
  311.    StartAddr       = AddrCache[delta];
  312.    goto REBUILDTABLE;
  313.   }
  314.   memcpy( SourceLineCache, TempSourceLineCache, AsmTableSize );         /*518*/
  315.   memcpy( AddrCache,TempAddrCache , AsmTableSize );                     /*518*/
  316.   goto BUILDTEXT;
  317.  }
  318. /*===========================================================================*/
  319.  
  320. /** Come here for Mixed Source/Disassembly view ******************************/
  321. /*                                                                           */
  322. /* We come into ascroll() with a delta value that tells us how far to        */
  323. /* move up or down in the disassembly view. What we will do is define        */
  324. /* a StartAddr and a StartLineNumber that we will use to build a             */
  325. /* set of display tables. The tables will be kept in static storage because  */
  326. /* we'll need them for some history.                                         */
  327. /*                                                                           */
  328. /* - delta < 0 ==> moving up...pgup,cursor up, etc.                          */
  329. /* - delta > 0 ==> moving dn...pgdn,cursor dn, etc.                          */
  330. /* - delta = 0 ==> coming if from source level or refreshing.                */
  331. /*                                                                           */
  332. /*                                                                           */
  333. /* delta = 0                                                                 */
  334. /*                                                                           */
  335. /* - ToggleAsm, i.e.  switching to asm view from source view.  In this case, */
  336. /*   the AF_SYNC flag will be set.  We are going to take the cursor line in  */
  337. /*   the source view and essentailly move it to the same relative position   */
  338. /*   in the disassembly view.  We will then expand up to fill in the margin  */
  339. /*   above and expand down to fill in the margin below.                      */
  340. /*                                                                           */
  341. /* - Single Step, Go, etc., in which case AF_ZOOM will be set.               */
  342. /*   If the hotaddr is already on the display, then don't rebuild            */
  343. /*   the tables, else move the hotaddr to the top of the display.            */
  344. /*                                                                           */
  345. /*                                                                           */
  346. /* delta < 0                                                                 */
  347. /*                                                                           */
  348. /*  In this case, we are going to get the StartAddr and StartLineNumber      */
  349. /*  from the first entries in the display buffers and build a margin of      */
  350. /*  delta lines above them and then expand down below the margin.            */
  351. /*                                                                           */
  352. /* delta > 0                                                                 */
  353. /*                                                                           */
  354. /*  This is the easy one. All we have to do is get the StartAddr and         */
  355. /*  StartLineNumber from the last entries in the current display buffers     */
  356. /*  and then expand down from there.                                         */
  357. /*                                                                           */
  358. /*                                                                           */
  359. /* The primary problem with all of the above cases is when a disassembled    */
  360. /* line overlays the top or bottom of the display.                           */
  361. /*                                                                           */
  362. /*****************************************************************************/
  363.  if( delta <= 0 )
  364.  {
  365.   if( delta == 0 )
  366.   {
  367.    if( fp->flags & AF_ZOOM )
  368.    {
  369.     if( IsOnAsmCRT( fp->hotaddr) )
  370.      goto BUILDTEXT;
  371.  
  372.     TopMargin = 0;
  373.     StartAddr = fp->topoff;
  374.     {
  375.      LNOTAB *pLnoTabEntry;
  376.  
  377.      DBMapInstAddr( StartAddr, &pLnoTabEntry, fp->pdf);
  378.      StartLineNumber = 0;
  379.      if( pLnoTabEntry )
  380.       StartLineNumber = pLnoTabEntry->lno;
  381.     }
  382.    }
  383.  
  384.    else if( fp->flags & ASM_VIEW_TOGGLE )
  385.    {
  386.     TopMargin = fp->csrline - fp->topline;
  387.     StartLineNumber = fp->csrline + fp->Nbias;
  388.     StartAddr = NULL;
  389.    }
  390.  
  391.    else if( fp->flags & ASM_VIEW_REFRESH )
  392.    {
  393.     goto BUILDTEXT;
  394.    }
  395.  
  396.    else if( fp->flags & ASM_VIEW_CHANGE )
  397.    {
  398.     TopMargin = fp->csrline - fp->topline;
  399.     StartLineNumber = fp->csrline + fp->Nbias;
  400.     StartAddr = NULL;
  401.    }
  402.    else if( fp->flags & ASM_VIEW_NEXT )
  403.    {
  404.     StartAddr = fp->AsmView.StartAddr;
  405.     StartLineNumber = fp->AsmView.StartLine;
  406.     goto BUILDTABLE;
  407.    }
  408.    else if( fp->flags & ASM_VIEW_MNE  )
  409.    {
  410.     DBDisa(fp->mid, 0, 0, 0 );
  411.     goto BUILDTEXT;
  412.    }
  413.   }
  414.  
  415.   else if( delta < 0 )
  416.   {
  417.    TopMargin = -delta;
  418.    StartLineNumber = SourceLineCache[0];
  419.    StartAddr       = AddrCache[0];
  420.    /**************************************************************************/
  421.    /* Check to see if we're bumping against the top of the display.          */
  422.    /* If so, then we proceed directly to build the table. We have to         */
  423.    /* rebuild the table even though it may have the same starting values     */
  424.    /* because it may be expanding/contracting due to the data window.        */
  425.    /**************************************************************************/
  426.    if( StartLineNumber == 1 && StartAddr == NULL )
  427.     goto BUILDTABLE;
  428.    if ( StartAddr != NULL )
  429.    {
  430.     /**************************************************************************/
  431.     /* If we come here then an executable line disassembly is overlapping     */
  432.     /* the top of the display.  We are going to quench the TopMargin, but     */
  433.     /* we only want to count the part of this disassembled line that will     */
  434.     /* be above the display.                                                  */
  435.     /*                                                                        */
  436.     /*  - get the span ( number of disassembly lines ) for this line.         */
  437.     /*  - get the cache index of the first address of this line.              */
  438.     /*  - find the index of StartAddr relative to the first addr.             */
  439.     /*  - adjust TopMargin for the partially expanded line + 1 for the        */
  440.     /*    source line.                                                        */
  441.     /*  - if TopMargin goes negative, then the number of lines "above"        */
  442.     /*    the display are more than needed to quench the delta, so            */
  443.     /*    we have to blow by the lines we don't want to finally get to        */
  444.     /*    the StartAddr that we "really" want.                                */
  445.     /*                                                                        */
  446.     /**************************************************************************/
  447.     span = DBGetAsmLines(fp,StartLineNumber,&addr,0);                    /*530*/
  448. ReCache1:                                                                /*530*/
  449.     idx  = DBDisa(fp->mid, addr, span, 0 );
  450.     for(index = idx ; icache[index].instaddr != StartAddr
  451.                     && icache[index].instaddr != ENDOFCACHE; index++ ){;}
  452.    /**************************************************************************/
  453.    /* We will not find the address in cache when we are looking at PLX    530*/
  454.    /* dis assembly which has name ID in it.                               530*/
  455.    /* To solve this Problem follow :                                      530*/
  456.    /*   - Read the 1st instruction stream                                 530*/
  457.    /*   - Check if it is a Jmp Instruction, If yes then get the offset.   530*/
  458.    /*   - Call DbgetAsmlines with Offset value and get the span           530*/
  459.    /*   - Set the addr to StartAddr we are looking for.                   530*/
  460.    /*   - Go back to Dbdisa to recache the cache.                         530*/
  461.    /**************************************************************************/
  462.    if (icache[index].instaddr == ENDOFCACHE)                            /*530*/
  463.    {                                                                    /*530*/
  464.       uint BytesRead, Skip = 0;                                         /*530*/
  465.  
  466.       ptr = GetCodeBytes( icache[0].instaddr,(uint)2, &BytesRead );     /*530*/
  467.       if ( *ptr++ == 0xEB )                                             /*530*/
  468.          Skip = (uint)*(ptr) + 2;                                       /*530*/
  469.       span = DBGetAsmLines(fp,StartLineNumber,&addr,Skip);              /*530*/
  470.       addr = StartAddr;                                                 /*530*/
  471.       goto ReCache1;                                                    /*530*/
  472.    }                                                                    /*530*/
  473.     span = index - idx + 1;
  474.     TopMargin -= span;
  475.     StartAddr = NULL;
  476.     if ( TopMargin < 0 )
  477.     {
  478.      TopMargin++;
  479.      for ( ; TopMargin < 0; TopMargin++,idx++ ){;}
  480.      StartAddr = icache[idx].instaddr;
  481.     }
  482.    }
  483.   }
  484.  
  485.   /****************************************************************************/
  486.   /* At this point, we are going to determine what line number we have to     */
  487.   /* back up to in order to quench the TopMargin.                             */
  488.   /****************************************************************************/
  489.   while( TopMargin > 0 && StartLineNumber > 1 )
  490.   {
  491.    StartLineNumber--;
  492.    if( (fp->flags & AF_HUGE) && (StartLineNumber <= fp->Nbias) )
  493.     pagefp( fp, StartLineNumber );
  494.    ptr=fp->source + fp->offtab[StartLineNumber-fp->Nbias] -1 ;
  495.    if (*ptr & LINE_OK)
  496.     TopMargin -= DBGetAsmLines(fp,StartLineNumber,&junk,0);             /*530*/
  497.    TopMargin--;
  498.   }
  499.  
  500.   /***************************************************************************/
  501.   /* If the TopMargin hits precisely at zero, then we have stopped on        */
  502.   /* a non-executable line or a disassembled line has expanded to exactly    */
  503.   /* fill the available space. In either case, the StartAddr = NULL.         */
  504.   /*                                                                         */
  505.   /* If the TopMargin < 0, then a disassembled line overlaps the top of      */
  506.   /* the display and we have to move back down within the line to the        */
  507.   /* correct StartAddr.                                                      */
  508.   /*                                                                         */
  509.   /* If TopMargin > 0, then we don't have enough lines to expand to          */
  510.   /* be able to fill it in so we go with the StartAddr and StartLineNumber   */
  511.   /* that we currently have. This will happen when we do something like      */
  512.   /* pgup from line 1.                                                       */
  513.   /*                                                                         */
  514.   /***************************************************************************/
  515.   if ( TopMargin == 0 && ( fp->flags & AF_SYNC ) )
  516.    StartAddr = NULL;
  517.  
  518.   else if( TopMargin < 0 )
  519.   {
  520.    span = DBGetAsmLines(fp,StartLineNumber,&StartAddr,0);               /*530*/
  521.    idx  = DBDisa(fp->mid, StartAddr , span, 0 );
  522.    TopMargin++;
  523.    for ( ; TopMargin < 0; TopMargin++,idx++ ){;}
  524.    StartAddr = icache[idx].instaddr;
  525.   }
  526.  
  527.  }
  528.  
  529.  else if( delta > 0 )
  530.  {
  531.   /***************************************************************************/
  532.   /* - test for start line past end of the source line table.                */
  533.   /***************************************************************************/
  534.   n = 0;
  535.   while(SourceLineCache[n] != ENDOFTABLE ) n++;
  536.   n = (delta >= n)?0:delta;
  537.   StartLineNumber = SourceLineCache[n];
  538.   StartAddr       = AddrCache[n];
  539.  }
  540.  
  541. BUILDTABLE:
  542. /*****************************************************************************/
  543. /* Now, we have a StartAddr and StartLineNumber to begin generating          */
  544. /* display tables.  The display tables will look like so:                    */
  545. /*                                                                           */
  546. /*   SourceLineNumber        AddrCache                                       */
  547. /*        .                     .                                            */
  548. /*        .                     .                                            */
  549. /*        .                     .                                            */
  550. /*        6                     0         <--- executable line 1st entry     */
  551. /*        6                     addr1     <--- executable line disasm entry. */
  552. /*        6                     addr2     <--- executable line disasm entry. */
  553. /*        6                     addr3     <--- executable line disasm entry. */
  554. /*        7                     0         <--- non-executable line.          */
  555. /*        8                     0         <--- non-executable line.          */
  556. /*        9                     .                                            */
  557. /*        .                     .                                            */
  558. /*        .                     .                                            */
  559. /*        -1 ( ENDOFTABLE )     .                                            */
  560. /*                                                                           */
  561. /*                                                                           */
  562. /* Normally, we will enter an (lno,0) for the first entry of an executable   */
  563. /* line and then expand the disassembly addresses below it.  But, in the case*/
  564. /* where an executable overlaps the top of the display, we only want part of */
  565. /* the line + disassembly.                                                   */
  566. /*                                                                           */
  567. /*****************************************************************************/
  568.  
  569.  TableDone = FALSE;
  570.  addr  = StartAddr;
  571.  lno   = StartLineNumber;
  572.  memset( TempSourceLineCache, 0 , AsmTableSize );                       /*518*/
  573.  memset( TempAddrCache , 0 , AsmTableSize );                            /*518*/
  574.  for ( row = 0 ; row < AsmRows && TableDone == FALSE ; row++ )
  575.  {
  576.   if( (fp->flags & AF_HUGE) &&
  577.       (lno > fp->Nbias + fp->Nlines) &&
  578.       (lno < fp->Tlines)
  579.     )
  580.    pagefp( fp, lno );
  581.  
  582.   if( lno > fp->Tlines )
  583.    break;
  584.   ptr=fp->source + fp->offtab[lno - fp->Nbias] -1 ;
  585.   if(*ptr & LINE_OK)
  586.   {
  587.    if( addr == NULL )
  588.    {
  589.     /*************************************************************************/
  590.     /* If we get here, then we are precisely at the start of an executable   */
  591.     /* line.                                                                 */
  592.     /*                                                                       */
  593.     /*  - make the lno,0 entry.                                              */
  594.     /*  - map the lno and get ready to add the disassembly lines.            */
  595.     /*                                                                       */
  596.     /*************************************************************************/
  597.     TempSourceLineCache[row] = lno;
  598.     TempAddrCache[row++] = NULL;
  599.     addr = DBMapLno(fp->mid, lno, fp->sfi, &read , fp->pdf );
  600.    }
  601.  
  602.    /**************************************************************************/
  603.    /* - get the index in the cache of the executable line.                   */
  604.    /* - reduce the span of the line for expansion of a partial line.         */
  605.    /*   ( when an executable line overlays the top of the display. )         */
  606.    /* - expand the line with the disassembly addresses.                      */
  607.    /* - upon entry to this loop, row is the index of the next entry          */
  608.    /*   to be written.                                                       */
  609.    /* - upon exit from this loop, row is one more than the last              */
  610.    /*   entry written to the display table so we decrement it.               */
  611.    /**************************************************************************/
  612.    span   = DBGetAsmLines(fp, lno, &FirstAddrForLine, 0);
  613. ReCache:
  614.    index  = DBDisa(fp->mid, FirstAddrForLine , span, 0 );
  615.  
  616.    for(; icache[index].instaddr != addr
  617.          && icache[index].instaddr != ENDOFCACHE; span--,index++){;}    /*530*/
  618.    /**************************************************************************/
  619.    /* We will not find the address in cache when we are looking at PLX    530*/
  620.    /* dis assembly which has name ID in it.                               530*/
  621.    /* To solve this Problem follow :                                      530*/
  622.    /*   - Read the 1st instruction stream                                 530*/
  623.    /*   - Check if it is a Jmp Instruction, If yes then get the offset.   530*/
  624.    /*   - Call DbgetAsmlines with Offset value and get the span           530*/
  625.    /*   - Set the FirstAddrForline to Current address we are looking for. 530*/
  626.    /*   - Go back to Dbdisa to recache the cache.                         530*/
  627.    /**************************************************************************/
  628.    if (icache[index].instaddr == ENDOFCACHE)                            /*530*/
  629.    {                                                                    /*530*/
  630.       uint BytesRead, Skip = 0;                                         /*530*/
  631.  
  632.       ptr = GetCodeBytes( icache[0].instaddr,(uint)2, &BytesRead );     /*530*/
  633.       if ( *ptr++ == 0xEB )                                             /*530*/
  634.          Skip = (uint)*(ptr) + 2;                                       /*530*/
  635.       span = DBGetAsmLines(fp,lno,&FirstAddrForLine,Skip);              /*530*/
  636.       FirstAddrForLine = addr;                                          /*530*/
  637.       goto ReCache;                                                     /*530*/
  638.    }                                                                    /*530*/
  639.    LastIndex = AsmRows - 1;                                             /*911*/
  640.    count  = 0;                                                          /*911*/
  641.    for ( ; row <= LastIndex && count < span ; index++,row++,count++ )   /*911*/
  642.    {                                                                    /*911*/
  643.     ULONG _address;                                                     /*911*/
  644.     ULONG lastaddr=0;                                                   /*911*/
  645.                                                                         /*911*/
  646.     _address = icache[index].instaddr;                                  /*911*/
  647.     if( _address == ENDOFCACHE )                                        /*911*/
  648.     {                                                                   /*911*/
  649.      ULONG LastAddrInLine;                                              /*911*/
  650.      ULONG LineSpan;                                                    /*911*/
  651.                                                                         /*911*/
  652.      LastAddrInLine = DBMapLno(fp->mid,                                 /*911*/
  653.                                lno,                                     /*911*/
  654.                                fp->sfi,                                 /*911*/
  655.                                &LineSpan,                               /*911*/
  656.                                fp->pdf);
  657.      LastAddrInLine += LineSpan;                                        /*911*/
  658.      if( lastaddr >= LastAddrInLine )                                   /*911*/
  659.       break;                                                            /*911*/
  660.                                                                         /*911*/
  661.      index = DBDisa(fp->mid, lastaddr , span, 0 );                      /*911*/
  662.      index++;                                                           /*911*/
  663.      _address = icache[index].instaddr;                                 /*911*/
  664.     }                                                                   /*911*/
  665.  
  666.     TempSourceLineCache[row] = lno;
  667.     TempAddrCache[row] = _address;
  668.     lastaddr = _address;
  669.    }
  670.    /**************************************************************************/
  671.    /* - decrement row to adjust for the overshoot.                           */
  672.    /* - bump to the next source line.                                        */
  673.    /* - init the addr for the next line.                                     */
  674.    /**************************************************************************/
  675.    row--;
  676.    lno++;
  677.    addr = NULL;
  678.   }
  679.   else
  680.   {
  681.    /**************************************************************************/
  682.    /* If the line is non-executable,then come here.                          */
  683.    /**************************************************************************/
  684.    TempSourceLineCache[row] = lno;
  685.    TempAddrCache[row] = NULL;
  686.    lno++;
  687.   }
  688.  }
  689.  /****************************************************************************/
  690.  /* On a pgdn or cursor down we want to anchor the bottom line to the        */
  691.  /* bottom of the display. So, we check to see if the display table is       */
  692.  /* full, and if not, we make an adjustment and go back and fill it up.      */
  693.  /*                                                                          */
  694.  /* - so, mark the end of the table.                                         */
  695.  /* - check to see if we have a full display.                                */
  696.  /* - if we don't then adjust delta and redo the table.                      */
  697.  /* - if all is ok, then copy the temp tables to the static tables.          */
  698.  /****************************************************************************/
  699.  TempSourceLineCache[row] = ENDOFTABLE;
  700.  for( row=0; TempSourceLineCache[row] != ENDOFTABLE; row++ ){;}
  701.  if( delta > 0 && row < AsmRows )
  702.  {
  703.   delta -= AsmRows - row;
  704.   if( delta < 0 )
  705.    delta = 0;
  706.   StartLineNumber = SourceLineCache[delta];
  707.   StartAddr       = AddrCache[delta];
  708.   goto BUILDTABLE;
  709.  }
  710.  memcpy( SourceLineCache, TempSourceLineCache, AsmTableSize );          /*518*/
  711.  memcpy( AddrCache,TempAddrCache , AsmTableSize );                      /*518*/
  712.  
  713. #if 0
  714. /*****************************************************************************/
  715. /* - turn this block on to dump the source line and address tables.          */
  716. /*****************************************************************************/
  717. {
  718.  int n=0;
  719.  
  720.  while( SourceLineCache[n] != ENDOFTABLE )
  721.  {
  722.   printf("\nn=%6d lno=%d addr=%x",n,SourceLineCache[n],AddrCache[n]);fflush(0);
  723.   n++;
  724.  }
  725. }
  726. #endif
  727.  
  728. BUILDTEXT:
  729.  /****************************************************************************/
  730.  /*                                                                          */
  731.  /* Set some values in the fp structure.                                     */
  732.  /*                                                                          */
  733.  /* - define RowsUsed - the number of display rows used in this view.        */
  734.  /* - set the topoff in the view or 0 if no disassembly lines.               */
  735.  /* - set the topline for the mixed view.                                    */
  736.  /* - save the starting values for this view for possible later restore.     */
  737.  /*                                                                          */
  738.  /****************************************************************************/
  739.  for( RowsUsed=0; SourceLineCache[RowsUsed] != ENDOFTABLE
  740.       && RowsUsed<AsmRows ; RowsUsed++ ){;} /*DLJ: with windows, display
  741.                                              window is smaller than compute window.*/
  742.  for(row=0;
  743.       SourceLineCache[row] != ENDOFTABLE && row<AsmRows
  744.      && !(fp->topoff=AddrCache[row]);row++){;}
  745.  
  746.  /************************************************************************402*/
  747.  /* we removed the setting of fp->topline.                                402*/
  748.  /************************************************************************402*/
  749.  
  750.  fp->AsmView.StartAddr = AddrCache[0];
  751.  fp->AsmView.StartLine = SourceLineCache[0];
  752.  
  753.  /****************************************************************************/
  754.  /* Now build the text buffer.                                               */
  755.  /*                                                                          */
  756.  /* - init the text buffer to all blanks.                                    */
  757.  /* - write in the background attributes effectively making AsmRows of       */
  758.  /*   blank lines.                                                           */
  759.  /* - get the cache index of the top addr in AddrCache.                      */
  760.  /* - build source lines and asm lines adding attributes to asm lines.       */
  761.  /* - define brkxline if for a line that has both a bkpt and is the exec     */
  762.  /*   line.                                                                  */
  763.  /* - terminate each line of display buffer with a \0. (To stop the display).*/
  764.  /* - display the text buffer.                                               */
  765.  /* - add underscores to the bkpt/exec line.                                 */
  766.  /*                                                                          */
  767.  /****************************************************************************/
  768.  memset( textbuf, ' ',TextBufSize);
  769.  cp = textbuf;
  770.  
  771.  for(row=0; row<(uint)AsmRows;++row,cp+=VideoCols+2)
  772.    *cp = ATTR_BKPT_OK_LINE;
  773.  
  774.  brkxline = 0;
  775.  index = -1;
  776.  if( fp->topoff != NULL )
  777.   index = DBDisa(fp->mid, fp->topoff, 1, 0 );
  778.  
  779.  StartLineNumber = AsmTop;                                              /*400*/
  780.  for ( cp = textbuf, row=0; row < (int)RowsUsed; ++row, cp += VideoCols+2 )
  781.  {
  782.   addr  = AddrCache[row];
  783.   if ( addr == NULL )
  784.   {
  785.    lno = SourceLineCache[row];
  786.    buildasmsrc( cp+1, fp, lno );
  787.    *cp = ATTR_SOURCE_LINE;
  788.   }
  789.   else
  790.   {
  791.    index = DBDisa(fp->mid, addr, 1, 0 );
  792.    buildasmline( cp+1, &icache[index]);
  793.  
  794.    /**************************************************************************/
  795.    /* - write the line display attribute in the first byte of the line.      */
  796.    /* - make a note of the line if we have a breakpoint on an execline.      */
  797.    /**************************************************************************/
  798.    *cp = ATTR_BKPT_OK_LINE;
  799.    if ( IfBrkOnAddr(AddrCache[row]) )
  800.     *cp = ATTR_BKPT_ON_LINE;
  801.    if( AddrCache[row] == GetExecAddr() )
  802.    {
  803.     if( *cp == ATTR_BKPT_OK_LINE )
  804.      *cp = ATTR_EXEC_LINE;
  805.     else
  806.      *cp = ATTR_BKPT_ON_EXEC_LINE;
  807.    }
  808.  
  809.    if( *cp == Attrib(vaXlineOn) )
  810.       brkxline = row+1;
  811.   }
  812.   *(cp + VideoCols + 1) = '\0';                                         /*400*/
  813.   putrc( StartLineNumber++, 0, cp );                                    /*400*/
  814.  }
  815.  
  816.  
  817.  /****************************************************************************/
  818.  /* Put blank rows on the screen when the assembly lines are less than    400*/
  819.  /* the number of AsmRows                                                 400*/
  820.  /****************************************************************************/
  821.  for ( row = RowsUsed ; row < AsmRows; ++row,cp += VideoCols+2)         /*400*/
  822.  {                                                                      /*400*/
  823.     *(cp + VideoCols + 1) = '\0';                                       /*400*/
  824.     putrc( StartLineNumber++, 0, cp );                                  /*400*/
  825.  }                                                                      /*400*/
  826.  
  827.  
  828.  if( brkxline )
  829.   putxb( AsmTop + brkxline - 1, '_' );
  830.  
  831.  /****************************************************************************/
  832.  /* Scan the table of stack return addresses looking for addresses that      */
  833.  /* may appear in the display table. If we find one, then add shading        */
  834.  /* to that line and add the level of the function in the call stack.        */
  835.  /****************************************************************************/
  836.  for( n=0; n < NActFrames; ++n )
  837.  {
  838.   i = lindex(AddrCache, RowsUsed, (ulong)ActFaddrs[n] );
  839.   if( i < RowsUsed )
  840.   {
  841.    putxb( AsmTop + i, ACTCALLSHADE );
  842.    ndigits = sprintf(digits, "%c (-%u)", Attrib(0), n+1);
  843.    ndigits -= 1;
  844.    putrc(AsmTop+i, VideoCols-ndigits, digits );
  845.   }
  846.  }
  847.  if(!iview) {
  848.  if(TestBit(Reg_Display,REGS386BIT))    /* if the register display flag   400*/
  849.     ShowvRegs();                        /* is set display the registers.  400*/
  850.  if(TestBit(Reg_Display,REGS387BIT))    /* if the coproregister display   401*/
  851.     ShowCoRegs();                       /* flag is set display the regs   401*/
  852.  }
  853.  return( 0);                            /*                                   */
  854. }                                       /* end ascroll()                     */
  855.  
  856. /*****************************************************************************/
  857. /* IsOnAsmCRT()                                                              */
  858. /*                                                                           */
  859. /* Description:                                                              */
  860. /*   Test for an address being currently in the display table.               */
  861. /*                                                                           */
  862. /* Parameters:                                                               */
  863. /*                                                                           */
  864. /*   fp        input - afile structure.                                      */
  865. /*   addr      input - address that we're testing.                           */
  866. /*                                                                           */
  867. /* Return:                                                                   */
  868. /*                                                                           */
  869. /*   TRUE or FALSE                                                           */
  870. /*                                                                           */
  871. /* Assumptions:                                                              */
  872. /*                                                                           */
  873. /*   none.                                                                   */
  874. /*                                                                           */
  875. /*****************************************************************************/
  876.  uint
  877. IsOnAsmCRT( uint addr )
  878. {
  879.  int    row;
  880.  if (SourceLineCache == NULL)                                           /*518*/
  881.    return(FALSE);                                                       /*518*/
  882.  for( row = 0;
  883.       SourceLineCache[row] != ENDOFTABLE && row<AsmRows;
  884.       row++ )
  885.   if( addr == AddrCache[row])
  886.    return( TRUE );
  887.  return(FALSE);
  888. }                                       /* end IsOnAsmCRT().                 */
  889.  
  890. /*****************************************************************************/
  891. /* RefreshAsmPart()                                                       519*/
  892. /*                                                                           */
  893. /* Description:                                                              */
  894. /*   Refreshs the screen with the dis assembly view from a given line        */
  895. /*   to the bottom of the screen                                             */
  896. /*                                                                           */
  897. /* Parameters:                                                               */
  898. /*                                                                           */
  899. /*   StartLine     input - Startline number on the screen.                   */
  900. /*   RowsSkip      input - Rows to be skipped.                               */
  901. /*                                                                           */
  902. /* Return:                                                                   */
  903. /*                                                                           */
  904. /* Assumptions:                                                              */
  905. /*                                                                           */
  906. /*   none.                                                                   */
  907. /*                                                                           */
  908. /*****************************************************************************/
  909. void RefreshAsmPart(int StartLine, int RowsSkip)                        /*519*/
  910. {                                                                       /*519*/
  911.   char *cp;                                                             /*519*/
  912.   int n,row;                                                            /*519*/
  913.   /***************************************************************************/
  914.   /* The disassembly view buffer has been already built, so simply scan   519*/
  915.   /* the buffer and skip the number of rows given.                        519*/
  916.   /* Then call putrc to start refreshing from the given start line.       519*/
  917.   /***************************************************************************/
  918.   cp = textbuf;                                                         /*519*/
  919.   for(n = 0; n < RowsSkip ; ++n , cp += VideoCols + 2){;}               /*519*/
  920.   for ( row = RowsSkip ; row < AsmRows; ++row,cp += VideoCols+2)        /*519*/
  921.     putrc( StartLine++, 0, cp );                                        /*519*/
  922.   if(TestBit(Reg_Display,REGS386BIT))   /* if the register display flag   519*/
  923.      ShowvRegs();                       /* is set display the registers.  519*/
  924.   if(TestBit(Reg_Display,REGS387BIT))   /* if the coproregister display   519*/
  925.      ShowCoRegs();                      /* flag is set display the regs   519*/
  926. }                                                                       /*519*/
  927. /*****************************************************************************/
  928. /* FreeDisasmViewBuffers()                                                813*/
  929. /*                                                                           */
  930. /* Description:                                                              */
  931. /*   Frees up all the buffers allocated for disassembly.                     */
  932. /*                                                                           */
  933. /* Parameters:                                                               */
  934. /*                                                                           */
  935. /* Return:                                                                   */
  936. /*                                                                           */
  937. /* Assumptions:                                                              */
  938. /*                                                                           */
  939. /*****************************************************************************/
  940. void FreeDisasmViewBuffers()
  941. {
  942.  if(icache){Tfree(icache);icache=NULL;}
  943.  if(textbuf){Tfree(textbuf);textbuf=NULL;}
  944.  if(TempAddrCache){ Tfree(TempAddrCache);TempAddrCache=NULL;}
  945.  if(TempSourceLineCache){ Tfree(TempSourceLineCache);TempSourceLineCache=NULL;}
  946.  if(AddrCache){ Tfree(AddrCache);AddrCache=NULL;}
  947.  if(SourceLineCache){ Tfree(SourceLineCache);SourceLineCache=NULL;}
  948. }
  949.