home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / VIEWASM.C < prev    next >
Text File  |  1996-02-05  |  34KB  |  583 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   viewasm.c                                                               */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*   assembler display formatting routines.                                  */
  7. /*                                                                           */
  8. /* History:                                                                  */
  9. /*                                                                           */
  10. /*   02/08/91 Creation of 32-bit SD86, from 16-bit version.                  */
  11. /*                                                                           */
  12. /*...16->32 port.                                                            */
  13. /*...                                                                        */
  14. /*... 02/08/91  100   Philip    port to 32 bit.                              */
  15. /*... 02/08/91  101   Joe       port to 32 bit.                              */
  16. /*... 02/08/91  102   Pratima   port to 32 bit.                              */
  17. /*... 02/08/91  103   Dave      port to 32 bit.                              */
  18. /*... 02/08/91  104                                                          */
  19. /*... 02/08/91  105   Christina port to 32 bit.                              */
  20. /*... 02/08/91  106   Srinivas  port to 32 bit.                              */
  21. /*... 02/08/91  107   Dave      port to 32 bit.                              */
  22. /*... 02/08/91  108   Dave      port to 32 bit.                              */
  23. /*... 02/08/91  109                                                          */
  24. /*... 02/08/91  110   Srinivas  port to 32 bit.                              */
  25. /*... 02/08/91  111   Christina port to 32 bit.                              */
  26. /*... 02/08/91  112   Joe       port to 32 bit.                              */
  27. /*... 02/08/91  113                                                          */
  28. /*... 02/08/91  114                                                          */
  29. /*... 02/08/91  115   Srinivas  port to 32 bit.                              */
  30. /*... 02/08/91  116   Joe       port to 32 bit.                              */
  31. /*                                                                           */
  32. /*...Release 1.00 (Pre-release 1)                                            */
  33. /*...                                                                        */
  34. /*... 07/09/91  213   srinivas  one byte memory operand problem.             */
  35. /*... 08/30/91  235   Joe       Cleanup/rewrite ascroll() to fix several bugs*/
  36. /*...                                                                        */
  37. /*...Release 1.08 (Pre-release 108 )                                         */
  38. /*...                                                                        */
  39. /*... 01/17/92  504   Joe       Can't step into 16 bit dll on 6.177H.        */
  40. /*...                                                                        */
  41. /**Includes*******************************************************************/
  42.                                         /*                                   */
  43. #include "all.h"                        /* SD86 include files                */
  44.                                         /*                                   */
  45. /**Variables defined**********************************************************/
  46. /*                                                                           */
  47. /*                                                                           */
  48. /**Externs********************************************************************/
  49. /*                                                                           */
  50. extern uint VideoCols;
  51. extern INSTR    *icache;                /* +1 for a NULL terminating sel. 235*/
  52. extern PtraceBuffer AppPTB;
  53. extern CmdParms      cmd;
  54. /*
  55. /**Begin Code*****************************************************************/
  56. /*                                                                           */
  57. /*****************************************************************************/
  58. /* buildasmline()                                                            */
  59. /*                                                                           */
  60. /* Description:                                                              */
  61. /*   build disassembly text line.                                            */
  62. /*                                                                           */
  63. /* Parameters:                                                               */
  64. /*   pbuf       -> buffer where text goes.                                   */
  65. /*   pinstr     -> cache structure for this line.                            */
  66. /*                                                                           */
  67. /* Return:                                                                   */
  68. /*                                                                           */
  69. /* Assumptions:                                                              */
  70. /*                                                                           */
  71. /*  The cached instruction info is a valid instruction. It cannot be the     */
  72. /*  terminating cache entry.                                                 */
  73. /*                                                                           */
  74. /*****************************************************************************/
  75. #define ADDRSIZE 9+1                    /* addr field size for ssss:oooo or  */
  76.                                         /*   oooooooo  format             108*/
  77. #define HEXSIZE  15+1                   /* hex field size                 108*/
  78. #define MNESIZE  MNEMBUFFSIZE+1         /* mnem field size                108*/
  79. #define TXTSIZE  22+1                   /* text field size                   */
  80. #define MEMSIZE  11                     /* memory reference field size.      */
  81. #define DATACOL  45                     /* memory reference for side source. */
  82. #define WALL     DATACOL + 11           /* vertical bar location.            */
  83. #define VBAR     179                    /* vertical bar location.            */
  84.  
  85.  void
  86. buildasmline(uchar *pbuf,INSTR *pinstr)
  87. {
  88.   uchar   *bp;                          /* ->start of line in text           */
  89.   uchar  *cp;                           /*                                   */
  90.   int     offset;                       /*                                   */
  91.   uchar  *s;                            /* ->into line in formatted text     */
  92.   ushort       Sel;                                                     /*607*/
  93.   ushort       Off;                                                     /*607*/
  94.  
  95.     bp = pbuf;                          /* initialize first line start       */
  96.  
  97. /*****************************************************************************/
  98. /*                                                                           */
  99. /* Fill in the text buffer with Sel:Off data in format  XXXX:XXXXbb  .       */
  100. /*                                                                           */
  101. /*****************************************************************************/
  102.  
  103.     s = bp;                             /* start ->into text at line's edge  */
  104.     if (pinstr->mod_type)               /* 32-bit instruction ?           108*/
  105.      utox8(pinstr->instaddr, s);        /* 8-byte address as an offset    108*/
  106.     else                                /* 16-bit instruction             108*/
  107.     {
  108.       Code_Flat2SelOff(pinstr->instaddr,&Sel,&Off);
  109.       utox4(Sel,s);                     /* sel portion of ssss:oooo   607 504*/
  110.       s += 4;                           /* bump past selector portion        */
  111.       *s++ = ':';                       /* put in ':' and bump to offset     */
  112.       utox4(Off,s);                     /* offset portion of ssss:ooo 607 504*/
  113.     }
  114.     offset = ADDRSIZE;
  115.  
  116. /*****************************************************************************/
  117. /*                                                                           */
  118. /* Fill in the hex instruction.                                              */
  119. /*                                                                           */
  120. /*****************************************************************************/
  121.  
  122.      s = bp + offset;
  123.      strcpy( s,pinstr->hex);
  124.      cp = s;
  125.      while(*cp++ != '\0'){;}
  126.      *--cp = ' ';
  127.      offset += HEXSIZE;                                                 /*108*/
  128.  
  129. /*****************************************************************************/
  130. /*                                                                           */
  131. /* Fill in the mnemonic.                                                     */
  132. /*                                                                           */
  133. /*****************************************************************************/
  134.  
  135.     s = bp + offset;                    /* bump past offset and two blanks   */
  136.     strcpy(s,pinstr->mne);
  137.     cp = s;
  138.     while(*cp++ != '\0'){;}
  139.     *--cp = ' ';
  140.     offset += MNESIZE;
  141.  
  142. /*****************************************************************************/
  143. /*                                                                           */
  144. /* Fill in the text.                                                         */
  145. /*                                                                           */
  146. /*****************************************************************************/
  147.  
  148.     s = bp + offset;
  149.     strcpy(s,pinstr->text);
  150.     while(*s++ != '\0'){;}
  151.     *--s = ' ';
  152.     offset += TXTSIZE;
  153.  
  154. /*****************************************************************************/
  155. /*                                                                           */
  156. /* Fill in the memory operand.                                               */
  157. /*                                                                           */
  158. /*****************************************************************************/
  159.  
  160.     s = bp + offset + 5;               /* pad line out to midline with ' 's */
  161.  
  162.     if( IsEspRemote() == FALSE )
  163.      buildopnd( s , pinstr );
  164.  
  165. }
  166.  
  167. /*****************************************************************************/
  168. /* buildopnd()                                                               */
  169. /*                                                                           */
  170. /* Description:                                                              */
  171. /*   build operand part of the disassembly.                                  */
  172. /*                                                                           */
  173. /* Parameters:                                                               */
  174. /*   s          -> to buffer location where operand is to be written.        */
  175. /*   pinstr     -> cache structure containing the instruction info.          */
  176. /*                                                                           */
  177. /* Return:                                                                   */
  178. /*                                                                           */
  179. /* Assumptions:                                                              */
  180. /*                                                                           */
  181. /*  pinstr->instaddr != NULL.  This implies a termination cache entry.       */
  182. /*                                                                           */
  183. /*****************************************************************************/
  184.   void
  185. buildopnd(uchar *s,INSTR *pinstr)
  186. {
  187.   uchar   type;                         /*                                   */
  188.   uchar  *appopptr;                     /* ->operand for current instruction */
  189.   uint    off;
  190.  
  191.     type = pinstr->type;
  192.     switch( type )
  193.     {                                   /* begin work on operand information */
  194.       case MEM8BIT:                     /* 8-bit memory operand ?            */
  195.         *( s += 11) = '[';              /* right justify for 8-bit operand   */
  196.         appopptr = grabopnd(            /* get a pointer to the operand hex  */
  197.                              pinstr,    /*   using Toll's packet information */
  198.                              1 );       /*  and indicate call is for 8 bits  */
  199.         if( appopptr != NULL )
  200.          utox2( *appopptr, ++s );       /* put in 8-bit operand           213*/
  201.         else
  202.          {++s;sprintf(s,"..");}
  203.         *( s + 2 ) = ']';               /* left justify for 8-bit operand    */
  204.         break;                          /* end 8-bit memory operand          */
  205.  
  206.  
  207.       case MEM16OR32BIT:                /* 16-bit memory operand ?           */
  208.         if (pinstr->OpSize)             /* 32-bit memory operand ?        108*/
  209.         {
  210.           *( s += 5 ) = '[';            /* right justify for operand         */
  211.           appopptr = grabopnd(          /* get a pointer to the operand hex  */
  212.                                pinstr,  /*   using Toll's packet information */
  213.                                4 );     /*  and indicate call is for 32 bits */
  214.           if( appopptr != NULL )
  215.            utox8( *( uint* ) appopptr, ++s ); /* put in 32-bit operand    108*/
  216.           else
  217.            {++s;sprintf(s,"........");}
  218.           *( s + 8 ) = ']';             /* left justify for 32-bit operand   */
  219.         }
  220.         else                            /* truly a 16-bit operand         108*/
  221.         {
  222.           *( s += 9 ) = '[';            /* right justify for 16-bit operand  */
  223.           appopptr = grabopnd(          /* get a pointer to the operand hex  */
  224.                                pinstr,  /*   using Toll's packet information */
  225.                                2 );     /*  and indicate call is for 16 bits */
  226.           if( appopptr != NULL )
  227.            utox4( *( uint* ) appopptr, ++s ); /* put in 16-bit operand       */
  228.           else
  229.            {++s;sprintf(s,"....");}
  230.           *( s + 4 ) = ']';             /* left justify for 16-bit operand   */
  231.         }
  232.         break;                          /* end 16-bit memory operand         */
  233.  
  234.       case MEM1616OR3216BIT:            /* 16:16 memory operand ?            */
  235.         if (pinstr->OpSize)             /* 32-bit memory operand ?        108*/
  236.         {
  237.           *( s ) = '[';                 /* right justify for 16:16 operand   */
  238.           appopptr = grabopnd(          /* get a pointer to the operand hex  */
  239.                                pinstr,  /*   using Toll's packet information */
  240.                                6 );     /*  and indicate call is for 16 bits */
  241.           if( appopptr != NULL )
  242.           {
  243.            utox4( *(( USHORT* ) appopptr + 2), ++s ); /* put in 16-bit sel opnd*/
  244.            *( s += 4 ) = ':';              /* put in colon separator         */
  245.            utox8( *( uint* ) appopptr, ++s ); /* put in 32-bit offset operand*/
  246.           }
  247.           else
  248.            {++s;sprintf(s,"....:........");}
  249.           *( s + 8 ) = ']';             /* left justify for 16:16 operand    */
  250.         }
  251.         else                            /* truly 16-bit mem opnd             */
  252.         {
  253.           appopptr = grabopnd(pinstr,4);
  254.           s+=4;
  255.           sprintf(s,"[....:....]");
  256.           if( appopptr != NULL )
  257.           {
  258.            utox4( *( (USHORT*)appopptr + 1), s+1);
  259.            utox4( *(USHORT*)appopptr, s+6);
  260.           }
  261.         }
  262.         break;                          /* end 16:16 memory operand          */
  263.  
  264.       case JMPIPDISP:                   /* jump to IP + displacement instr ? */
  265.       case CALLIPDISP:                  /* call to IP + displacement instr ? */
  266.         if (pinstr->mod_type)           /* 32-bit instruction ?           108*/
  267.         {
  268.           *( s +=5 ) = '[';             /* right justify for operand         */
  269.           off=pinstr->instaddr+         /* offset of the instruction.        */
  270.               (uint)pinstr->offset +    /* relative offset in instruction.   */
  271.               (uint)pinstr->len;        /* adjustment for instruction length.*/
  272.           utox8( off, ++s );            /* target EIP                        */
  273.           *( s + 8 ) = ']';             /* left justify for 32-bit opnd   108*/
  274.         }
  275.         else                            /* 16-bit instruction             108*/
  276.         {
  277.           *( s+=4 ) = '[';              /* right justify for operand         */
  278.           utox4( AppPTB.CS, ++s );      /* put in cs selector             101*/
  279.           *( s += 4 ) = ':';            /* colon separator                   */
  280.           off=LoFlat(pinstr->instaddr) + /* offset of the instruction.       */
  281.               (uint)pinstr->offset +    /* relative offset in instruction.   */
  282.               (uint)pinstr->len;        /* adjustment for instruction length.*/
  283.           utox4( off , ++s);            /* put in target ip.                 */
  284.           *( s + 4 ) = ']';             /* left justify for 16:16 operand    */
  285.         }
  286.         break;                          /* end jump/call to IP + disp instr  */
  287.  
  288.       case ILLEGINST:                   /* illegal instruction ?             */
  289.       case NOOPND:                      /* no operand information ?          */
  290.         break;                          /* end no operand information        */
  291.     }                                   /* end work on operand information   */
  292. }
  293.  
  294. /*****************************************************************************/
  295. /* selreg                                                                    */
  296. /*                                                                           */
  297. /* Description:                                                              */
  298. /*   returns a selector register value.                                      */
  299. /*                                                                           */
  300. /* Parameters:                                                               */
  301. /*   retreg     Dave Toll's register code for the selector register.         */
  302. /*                                                                           */
  303. /* Return:                                                                   */
  304. /*   selvalue   contents of the indicated selector register.                 */
  305. /*                                                                           */
  306. /*****************************************************************************/
  307.   uint
  308. selreg(uint retreg)                     /* register code for a selector reg  */
  309. {                                       /* begin selreg                      */
  310.   switch( retreg )
  311.   {                                     /* begin deciphering register code   */
  312.     case RETREGDS:                      /* selector is the DS register ?     */
  313.       return( AppPTB.DS );              /* give the bugger the DS value   101*/
  314.  
  315.     case RETREGSS:                      /* selector is the SS register ?     */
  316.       return( AppPTB.SS );              /* give the bugger the SS value   101*/
  317.  
  318.     case RETREGES:                      /* selector is the ES register ?     */
  319.       return( AppPTB.ES );              /* give the bugger the ES value   101*/
  320.  
  321.     case RETREGCS:                      /* selector is the CS register ?     */
  322.       return( AppPTB.CS );              /* give the bugger the CS value   101*/
  323.  
  324.     default:
  325.       return(0);
  326.  
  327.   }                                     /* end deciphering register code     */
  328.  
  329. }                                       /* end selreg                        */
  330.  
  331. /*****************************************************************************/
  332. /* BaseVal()                                                                 */
  333. /*                                                                           */
  334. /* Description:                                                              */
  335. /*   returns a segment(for 16 bit) + base offset.                            */
  336. /*                                                                           */
  337. /* Parameters:                                                               */
  338. /*   pinstr     structure describing the instruction from Dave Toll's        */
  339. /*              disassembler.                                                */
  340. /*                                                                           */
  341. /* Return:                                                                   */
  342. /*   base       segment + base.                                              */
  343. /*                                                                           */
  344. /*****************************************************************************/
  345. ULONG BaseVal(INSTR *pinstr)
  346. {                                       /* begin offreg                      */
  347.  ULONG basevalue;
  348.   switch( pinstr->base )
  349.   {
  350.     case RETREGAX:
  351.     case RETREGBX:
  352.     case RETREGCX:
  353.     case RETREGDX:
  354.     case RETREGBP:
  355.     case RETREGSP:
  356.     case RETREGSI:
  357.     case RETREGDI:
  358. base16:
  359.      basevalue = selreg(pinstr->reg);
  360.      basevalue = Data_SelOff2Flat( basevalue,0);
  361.      switch( pinstr->base )
  362.      {
  363.       case RETREGAX:
  364.         return( basevalue + (AppPTB.EAX&0x0000FFFF));
  365.  
  366.       case RETREGBX:
  367.         return( basevalue + (AppPTB.EBX&0x0000FFFF));
  368.  
  369.       case RETREGCX:
  370.         return( basevalue + (AppPTB.ECX&0x0000FFFF));
  371.  
  372.       case RETREGDX:
  373.         return( basevalue + (AppPTB.EDX&0x0000FFFF));
  374.  
  375.       case RETREGBP:
  376.         return( basevalue + (AppPTB.EBP&0x0000FFFF));
  377.  
  378.       case RETREGSP:
  379.         return( basevalue + (AppPTB.ESP&0x0000FFFF));
  380.  
  381.       case RETREGSI:
  382.         return( basevalue + (AppPTB.ESI&0x0000FFFF));
  383.  
  384.       case RETREGDI:
  385.         return( basevalue + (AppPTB.EDI&0x0000FFFF));
  386.  
  387.       case RETREGNONE:
  388.         return(basevalue);
  389.      }
  390.      break;
  391.  
  392.     case RETREGEAX:                     /* offset is the EAX register ?   108*/
  393.       return( AppPTB.EAX );             /* give the bugger the EAX value  108*/
  394.  
  395.     case RETREGEBX:                     /* offset is the EBX register ?   108*/
  396.       return( AppPTB.EBX);              /* give the bugger the EBX value  108*/
  397.  
  398.     case RETREGECX:                     /* offset is the ECX register ?   108*/
  399.       return( AppPTB.ECX );             /* give the bugger the ECX value  108*/
  400.  
  401.     case RETREGEDX:                     /* offset is the EDX register ?   108*/
  402.       return( AppPTB.EDX);              /* give the bugger the EDX value  108*/
  403.  
  404.     case RETREGEBP:                     /* offset is the EBP register ?   108*/
  405.       return( AppPTB.EBP);              /* give the bugger the EBP value  108*/
  406.  
  407.     case RETREGESP:                     /* offset is the ESP register ?   108*/
  408.       return( AppPTB.ESP);              /* give the bugger the ESP value  108*/
  409.  
  410.     case RETREGESI:                     /* offset is the ESI register ?   108*/
  411.       return( AppPTB.ESI);              /* give the bugger the ESI value  108*/
  412.  
  413.     case RETREGEDI:                     /* offset is the EDI register ?   108*/
  414.       return( AppPTB.EDI);              /* give the bugger the EDI value  108*/
  415.  
  416.     case RETREGNONE:                    /* no offset register used ?         */
  417.       if( pinstr->mod_type == BIT16 )
  418.        goto base16;
  419.       return( 0 );                      /* => this offset is zero            */
  420.   }                                     /* end deciphering register code     */
  421.   return(0);
  422. }                                       /* end offreg                        */
  423.  
  424. /*****************************************************************************/
  425. /* offreg                                                                    */
  426. /*                                                                           */
  427. /* Description:                                                              */
  428. /*   returns an offset register value.                                       */
  429. /*                                                                           */
  430. /* Parameters:                                                               */
  431. /*   retreg     Dave Toll's register code for the offset register.           */
  432. /*                                                                           */
  433. /* Return:                                                                   */
  434. /*   offvalue   contents of the indicated offset register.                   */
  435. /*                                                                           */
  436. /*****************************************************************************/
  437.   uint
  438. offreg(uint retreg)                     /* register code for a offset reg    */
  439. {                                       /* begin offreg                      */
  440.   switch( retreg )
  441.   {                                     /* begin deciphering register code   */
  442.     case RETREGAX:                      /* offset is the AX register ?       */
  443.       return( AppPTB.EAX&0x0000FFFF);   /* give the bugger the AX value   108*/
  444.  
  445.     case RETREGBX:                      /* offset is the BX register ?       */
  446.       return( AppPTB.EBX&0x0000FFFF);   /* give the bugger the BX value   108*/
  447.  
  448.     case RETREGCX:                      /* offset is the CX register ?       */
  449.       return( AppPTB.ECX&0x0000FFFF);   /* give the bugger the CX value   108*/
  450.  
  451.     case RETREGDX:                      /* offset is the DX register ?       */
  452.       return( AppPTB.EDX&0x0000FFFF);   /* give the bugger the DX value   108*/
  453.  
  454.     case RETREGBP:                      /* offset is the BP register ?       */
  455.       return( AppPTB.EBP&0x0000FFFF);   /* give the bugger the BP value   108*/
  456.  
  457.     case RETREGSP:                      /* offset is the SP register ?       */
  458.       return( AppPTB.ESP&0x0000FFFF);  /* give the bugger the SP value   108*/
  459.  
  460.     case RETREGSI:                      /* offset is the SI register ?       */
  461.       return( AppPTB.ESI&0x0000FFFF);   /* give the bugger the SI value   108*/
  462.  
  463.     case RETREGDI:                      /* offset is the DI register ?       */
  464.       return( AppPTB.EDI&0x0000FFFF);   /* give the bugger the DI value   108*/
  465.  
  466.     case RETREGEAX:                     /* offset is the EAX register ?   108*/
  467.       return( AppPTB.EAX );             /* give the bugger the EAX value  108*/
  468.  
  469.     case RETREGEBX:                     /* offset is the EBX register ?   108*/
  470.       return( AppPTB.EBX);              /* give the bugger the EBX value  108*/
  471.  
  472.     case RETREGECX:                     /* offset is the ECX register ?   108*/
  473.       return( AppPTB.ECX );             /* give the bugger the ECX value  108*/
  474.  
  475.     case RETREGEDX:                     /* offset is the EDX register ?   108*/
  476.       return( AppPTB.EDX);              /* give the bugger the EDX value  108*/
  477.  
  478.     case RETREGEBP:                     /* offset is the EBP register ?   108*/
  479.       return( AppPTB.EBP);              /* give the bugger the EBP value  108*/
  480.  
  481.     case RETREGESP:                     /* offset is the ESP register ?   108*/
  482.       return( AppPTB.ESP);              /* give the bugger the ESP value  108*/
  483.  
  484.     case RETREGESI:                     /* offset is the ESI register ?   108*/
  485.       return( AppPTB.ESI);              /* give the bugger the ESI value  108*/
  486.  
  487.     case RETREGEDI:                     /* offset is the EDI register ?   108*/
  488.       return( AppPTB.EDI);              /* give the bugger the EDI value  108*/
  489.  
  490.     case RETREGNONE:                    /* no offset register used ?         */
  491.       return( 0 );                      /* => this offset is zero            */
  492.   }                                     /* end deciphering register code     */
  493.   return(0);
  494. }                                       /* end offreg                        */
  495.  
  496. /*****************************************************************************/
  497. /* grabopnd                                                                  */
  498. /*                                                                           */
  499. /* Description:                                                              */
  500. /*   returns a pointer to the "read in" hex operand.                         */
  501. /*                                                                           */
  502. /* Parameters:                                                               */
  503. /*   pcktptr    ->Dave Toll's disassembler communications packet.            */
  504. /*   opndsize   size of our operand (in bytes).                              */
  505. /*                                                                           */
  506. /* Return:                                                                   */
  507. /*   p          ->hex operand bytes read in.                                 */
  508. /*                                                                           */
  509. /*****************************************************************************/
  510.   uchar*
  511. grabopnd(INSTR *cptr,uint opndsize)     /* cptr : -> cached instruction info */
  512.                                         /* opndsize : size of operand to grab*/
  513. {                                       /* begin grabopnd                    */
  514.   uint    opndptr;                      /* ->operand in user's app space  101*/
  515.   uchar   *appcdptr;                    /* ->application code read in        */
  516.   uint    read;                         /* number of bytes read in by DBGetCS*/
  517.   ULONG   basevalue;                    /* base register value            108*/
  518.   uint    indexvalue;                   /* index register value           108*/
  519.  
  520.   basevalue  = BaseVal( cptr );         /* get a base value.                 */
  521.   indexvalue = offreg( cptr->index );   /* get index register value       108*/
  522.   indexvalue = indexvalue<<cptr->scale; /* scale the index reg            108*/
  523.   opndptr = basevalue +                 /* calculate operand's address    108*/
  524.             indexvalue +
  525.             ( uint ) cptr->offset;
  526.  
  527.   appcdptr = DBGet(                     /* ->memory operand which is read i  */
  528.                     opndptr,            /*   starting at operand address for */
  529.                     opndsize,           /*   a maximum of opndsize bytes     */
  530.                     &read );            /*   (but maybe less available)      */
  531.  
  532.  
  533.  
  534.  
  535.  
  536.   return( appcdptr );                   /* give caller ->operand hex         */
  537. }                                       /* end grabopnd                      */
  538.  
  539.  
  540. /*****************************************************************************/
  541. /* buildasmsrc()                                                             */
  542. /*                                                                           */
  543. /* Description:                                                              */
  544. /*   display source code along with assembler.                               */
  545. /*                                                                           */
  546. /*                                                                           */
  547. /* Parameters:                                                               */
  548. /*                                                                           */
  549. /*   cp        input - -> to start of text buffer line.                      */
  550. /*   fp        input - afile for this asm window.                            */
  551. /*   lno       input - executable line number for the source.                */
  552. /*                                                                           */
  553. /* Return:                                                                   */
  554. /*                                                                           */
  555. /*                                                                           */
  556. /* Assumptions:                                                              */
  557. /*                                                                           */
  558. /*   lno is a valid executable line number.                                  */
  559. /*                                                                           */
  560. /*****************************************************************************/
  561.  void
  562. buildasmsrc(uchar *cp,AFILE *fp,uint lno)
  563. {                                       /*                                   */
  564.  uchar     line[ MAXCOLS+1 ];           /* a source line buffer.             */
  565.  uchar    *ptr;                         /* a ptr.                            */
  566.  uint      i;                           /* just an i.                        */
  567.  
  568. /*****************************************************************************/
  569. /* The lno value at this point may need to be adjusted for a HUGE, > 64k,    */
  570. /* source file. The Nbias value is the number of lines in the source file    */
  571. /* that have been skipped prior to what is currently loaded in the source    */
  572. /* buffer for this afile.                                                    */
  573. /*                                                                           */
  574. /*****************************************************************************/
  575.  
  576.  lno -= fp->Nbias ;                     /* adjust for HUGE source.        235*/
  577.  ptr = fp->source + fp->offtab[lno];    /* -> to text line in source buffer. */
  578.  i  = Decode(ptr,line);                 /* decode/copy src text to line buf. */
  579.  i = (i < VideoCols) ? i : VideoCols;   /* limit to video cols               */
  580.  strncpy(cp , line, i );
  581.  
  582. }
  583.