⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 agdi.cpp

📁 8051编程例子讲解 一些基本使用方法通过例子有详细说明
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if (pBX == NULL)  {               // setup a temporary Bp
      if (nAdr != 0xFFFFFFFF)  {      // example: g,main
        pBX = &abp;
        abp.type    = AG_ABREAK;
        abp.enabled = 1;
        abp.rcount  = 1;
        abp.ocount  = 1;
        abp.Adr     = nAdr;
        if (!SetClrBp (1, pBX))  {    // setup temporary break
          return;
        }
      }
    }

    GoCmd();

    if (abp.enabled)  {          // clear temporary break
      SetClrBp (0, &abp);
      pBX = NULL;
    }

    GoMode = 0;

    if (PlayDead) return;
    curPC = ReadPC();
    if (BrkWalk (curPC)) break;
  }

  SaCBreaks (0, nAdr);           // set breakpoints (1:=set, 0:=clear)
}



/*
 * Go/Step/Stop commands
 */

_EXPO_ U32 AG_GoStep (U16 nCode, U32 nSteps, GADR *pA)  {
  U32     nE;

  if (PlayDead) return (0);           // driver is disconnected.

  nE = 0;                             // clear error code
  switch (nCode)  {
    case AG_STOPRUN:                  // Stop Go/Step.
      StopRun = 1;
      nE = StopExec();                // nE:  1=Stopped, 0=executing
      if (nE == 1) iRun = 0;          // stopped.
      if (!iRun)  {
        Invalidate();                 // registers, caches, etc.
      }
      NumRecs = 0;                    // clear 'number of trace records'
      break;

    case AG_NSTEP:                    // execute 'nSteps' instruction steps
      iRun = 1;                       // 'executing'
      for ( ; nSteps != 0 ; --nSteps )  {
        if (StopRun) break;           // Stop-Button was pressed
        if (Step() != 0x01) break;    // 0x01 means 'Ok.'
      }
      StopRun = 0;                    // clear Stop-Button flag.
      Invalidate();                   // registers, caches, etc.
      iRun = 0;                       // clear 'executing' flag
      NumRecs = 0;                    // clear 'number of trace records'
      break;

    case AG_GOTILADR:                 // run til 'pA->Adr' or some Bp,
      iRun = 1;                       // whichever comes first
      GoUntil (pA->Adr);
      StopRun = 0;
      Invalidate();                   // registers, caches, etc.
      iRun = 0;                       // clear 'executing' flag
      NumRecs = 0;                    // clear 'number of trace records'
      break;

    case AG_GOFORBRK:                 // run forever or till some Bp reached.
      iRun = 1;
      GoUntil (0xFFFFFFFF);           // means 'go forever'
      StopRun = 0;
      Invalidate();                   // registers, caches, etc.
      iRun = 0;                       // clear 'executing' flag
      NumRecs = 0;                    // clear 'number of trace records'
      break;
  }

  if (PlayDead)  {                    // target not connected
    StopTarget();                     // shut it down
    PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0); // terminate ourselves
  }
  else  {
    GetRegs();                        // get target registers
    *pCURPC = REG51.nPC;              // let uVision2 know about PC...
  }
  return (nE);
}

/*
 * Serial Window read/write
 */

_EXPO_ U32 AG_Serial (U16 nCode, U32 nSerNo, U32 nMany, void *vp)  {
  struct SerAS  va;

  if (PlayDead) return (0);    // driver is disconnected.
  va.n1 = nSerNo;              // 0:=Serial #1,  1:=Serial #2
  va.n2 = nMany;               // number of items to write

  switch (nCode)  {
    case AG_SERBOUT:           // write nMany bytes to Serial #1 Window of uVision2
      va.v.pS = (SC8 *) vp;    // content
      SendMessage (hMfrm, Uv2Msg, MSG_UV2_SERBOUT, (LPARAM) &va);
      break;

    case AG_SERWOUT:           // write nMany words to Serial #1 Window
//    va.v.pW = (U16 *) vp;    // content
//    SendMessage (hMfrm, Uv2Msg, MSG_UV2_SERWOUT, (LPARAM) &va);
      break;

    case AG_SERXIN:            // Key was pressed in Serial Window #1 or #2
//    WriteToSerPort (nSerNo, (char *) vp, nMany); // Output to serial interface
//    nSerno := Window number (#0 or #1)
//    vp     := &character(s) to send
//    nMany  := number of characters to send
      break;
  }
  return (0);
}


#if 0  // Example on how to output a string to uVision's serial window #1:
  char szSerTxt[] = "this should appear in serial window #1";
  AG_Serial (AG_SERBOUT, 0, sizeof (szSerTxt) - 1, (void *) szSerTxt);
#endif



/*
 * Calculate Trace History
 */
 
#define MAXTRC   256                // assume 1024 (use a power of two value)

static DWORD TracePC [MAXTRC];      // trace code-address buffer


static int CalcNumRecords (void)  {
  if (NumRecs == 0)  {              // seems to be invalidated

//---just a test vector:
    TracePC [0] = 0x0000000;        // Slot[0] not used.
    TracePC [1] = 0x0000047;
    TracePC [2] = 0x0000049;
    TracePC [3] = 0x000004B;
    TracePC [4] = 0x000004C;
    TracePC [5] = 0x0000050;
    TracePC [6] = 0x0000050;
    TracePC [7] = 0x0000050;
    TracePC [8] = 0x0000050;
    TracePC [9] = 0x0000050;
    TracePC[10] = 0x0000050;
    NumRecs = 10;                   // assume 10 entries

//  Calc:
//  TracePC [0] := unused
//  TracePC [1] := newest code address
//    ..
//  TracePC [n] := oldest code address  ( n >= 0, n < MAXTRC )
  }
  return (NumRecs);
}


/*
 * Trace-History access function:
 *   - the first call is always nCode 3 for 'query number of records'
 *   - then nCode 0 / 1 are activated.
 * Note: Emulator hardware must support tracing
 */

_EXPO_ U32 AG_HistFunc (U32 nCode, I32 indx, I32 dir, void *vp)  {
  U32     nR = 0;

  if (PlayDead) return (0);

  switch (nCode)  {
    case 0:                   // Function #0: get Hist index
      if (NumRecs == 0) break;
      if (dir)  {             // dir, 1:=towards older entries
        if (indx < NumRecs)  {
          nR = indx + 1;
        }
      }
      else  {                 // dir, 0:=towards newer entries
        if (indx > 0) nR = indx - 1;
        else          nR = 0;
      }
      break;

    case 1:                   // Function #1: GetTracePC
      if (indx >= 0 && indx < MAXTRC)  {
        nR  = TracePC [indx]; // get PC of trace record 'indx' 
        nR |= amCODE << 24;
      }
      break;

    case 2:                   // Function #2: GetHistRegs
// this function should be ignored since regs are not recorded anyway.
      break;                  // get recorded regs of record 'indx'

    case 3:                   // Function #3: get Nr. of entries
      if (iRun) return (0);   // block view-trace while running

//   - Find out the number of instructions based on the TRACE-Sfrs up to,
//     but not including the current PC
//***NOTE: make sure that CalcNumRecords() is as fast as possible since
//         it is called many times due to Billy's OnUpdate() handling.
      NumRecs = CalcNumRecords();
      nR      = NumRecs;      // return-value.
      break;
  }

  if (PlayDead == 1)  {
    StopTarget();
    PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
  }
  return (nR);
}


/*
 * Register View Management
 */

struct rGroup rGroups[] =  {
  { 0x00, 0x01, "Regs",   },      // Group 0, show expanded
  { 0x00, 0x01, "Sys",    },      // Group 1, show expanded
};

struct rItem rItems[] =  {
//--desc-nGi-nItem-szReg[]--isPC-cc-iHig--
  { 0x01, 0, 0x00, "r0",      0, 1, 0,  },
  { 0x01, 0, 0x01, "r1",      0, 1, 0,  },
  { 0x01, 0, 0x02, "r2",      0, 1, 0,  },
  { 0x01, 0, 0x03, "r3",      0, 1, 0,  },
  { 0x01, 0, 0x04, "r4",      0, 1, 0,  },
  { 0x01, 0, 0x05, "r5",      0, 1, 0,  },
  { 0x01, 0, 0x06, "r6",      0, 1, 0,  },
  { 0x01, 0, 0x07, "r7",      0, 1, 0,  },

  { 0x01, 1, 0x10, "a",       0, 1, 0,  },
  { 0x01, 1, 0x11, "b",       0, 1, 0,  },
  { 0x01, 1, 0x12, "sp",      0, 1, 0,  },
  { 0x01, 1, 0x13, "dptr",    0, 1, 0,  },
  { 0x01, 1, 0x14, "PC  $",   1, 1, 0,  },
//{ 0x01, 1, 0x15, "states",  0, 0, 0,  },
//{ 0x01, 1, 0x16, "sec",     0, 0, 0,  },

  { 0x01, 1, 0x100,"psw",     0, 1, 0,  },
  { 0x01, 1, 0x101,"p",       0, 1, 0,  },  // child-0
  { 0x01, 1, 0x102,"f1",      0, 1, 0,  },  // child-1
  { 0x01, 1, 0x103,"ov",      0, 1, 0,  },
  { 0x01, 1, 0x104,"rs",      0, 1, 0,  },
  { 0x01, 1, 0x105,"f0",      0, 1, 0,  },
  { 0x01, 1, 0x106,"ac",      0, 1, 0,  },
  { 0x01, 1, 0x107,"cy",      0, 1, 0,  },
  { 0x01, 1, 0x108,"",        0, 0, 0,  },  // End of 'psw' children.
};


struct bmsk  {
  U16       mask;
  I32       shft;
};

static const struct bmsk mx51[] = {
  { 0x0001,  0, },   // P
  { 0x0002,  1, },   // F1
  { 0x0004,  2, },   // OV
  { 0x0018,  3, },   // RS0, RS1
  { 0x0020,  5, },   // F0
  { 0x0040,  6, },   // AC
  { 0x0080,  7, },   // CY
};

static BYTE           nRmode;
static BYTE           nRstat;
static RG51              uRg;         // shadow registers
static char        szV [128];         // temporary buffer


/*
 * uVision2 want's to display some registers value...
 */

static void RegGet (RITEM *vp, int nR)  {
  GVAL      v;
  U32       n, z;

  if (PlayDead) return;                    // target is disconnected...

  switch (nR & 0xF0000000)  {
    case UPR_NORMAL:                       // Setup Normal Regs
      GetRegs();                           // update our local regs
      uRg    = REG51;                      // capture current regs
      nRmode = 0;                          // normal mode
      *pCURPC = uRg.nPC;                   // C:0xnnnn

      if (PlayDead)  {                     // target died...
        StopTarget();
        PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);  // Bye
      }
      return;

    case UPR_HIST:                         // Setup History Regs
//--- currently not supported !
//    v.i32 = nR & 0xFFFF;                 // History index (max. 64K entries)
//    if (ioc.numtra != MAXTRC) v.i32 = (ioc.numtra - v.i32) & (MAXTRC - 1);
//    else                      v.i32 = (ioc.curtra - v.i32) & (MAXTRC - 1);
//    uRg    = *(((REG51 *) ioc.trap) + v.i32);  // HistRegs
//    nRstat = 1;                          // mark 'PSW' as current.
//    nRmode = 1;                          // history mode
      return;
  }

  v.u64     = 0;
  vp->iDraw = 0;

  switch (vp->nItem)  {
    case 0x00:  case 0x01:  case 0x02:  case 0x03:
    case 0x04:  case 0x05:  case 0x06:  case 0x07:
      v.uc = uRg.Rn [vp->nItem & 0x07];         // current Rn
x8:   if (v.uc != vp->v.uc || vp->szVal[0] == 0)  {
        sprintf (vp->szVal, "0x%02x", v.u32);
      }
      break;
    case 0x10: v.uc = uRg.acc;  goto x8;  // A
    case 0x11: v.uc = uRg.b;    goto x8;  // B
    case 0x12: v.uc = uRg.sp;   goto x8;  // SP
    case 0x13:                            // DPTR
      v.u16 = ((U16) uRg.dph) << 8 | (U16) uRg.dpl;
      if (v.u16 != vp->v.u16 || vp->szVal[0] == 0)  {
        sprintf (vp->szVal, "0x%04x", v.u32);
      }
      break;

    case 0x14:                            // 'PC  $'
      if (uRg.nPC != vp->v.u32 || vp->szVal[0] == 0)  {
        sprintf (vp->szVal, "0x%04x", uRg.nPC & 0xFFFF);
        vp->iDraw = 1;
      }
      vp->v.u32 = uRg.nPC;
      vp->iHigh = 0;                      // never highlighted
      return;

    case 0x15:                            // States
    case 0x16:                            // Seconds
// not relevant in target mode
      return;

    case 0x100:                           // PSW
    case 0x101:                           // P
    case 0x102:                           // F1
    case 0x103:                           // OV
    case 0x104:                           // RS
    case 0x105:                           // F0
    case 0x106:                           // AC
    case 0x107:                           // Cy
      if (vp->nItem == 0x100)  {          // PSW
        v.uc = uRg.psw;                   // want PSW only
        goto x8;
      }
//--- want some bit from PSW:
      n = vp->nItem - 0x101;              // use item-number as index
      z = uRg.psw & mx51[n].mask;         // masked value, not normalized
      v.u32 = z >> mx51[n].shft;          // normalize
      if (v.u32 != vp->v.u32 || vp->szVal[0] == 0)  {  // value changed
        sprintf (vp->szVal, "%d       ", v.u32);       // spaces to ease mouse hit.
      }
      break;
  }

  if (v.u32 == vp->v.u32)  {              // value unchanged
    if (vp->iHigh)  {                     // item is currently highlighted
      vp->iHigh = 0;                      // clear highlight color
      vp->iDraw = 1;                      // need repaint.
    }
  }
  else  {                                 // value changed
    vp->iHigh = 1;                        // highlight
    vp->iDraw = 1;                        // need repaint
  }
  vp->v.u64 = v.u64;                      // update 'On Screen' value
}


/*
 * uVision2 want's to change some registers value...
 */

static I32 RegSet (RITEM *vp, GVAL *pV)  {
  I32       n;
  U16     val;

  if (nRmode == 1) return (0);       // Error: can't change HistRegs !
  if (PlayDead)    return (0);       // cancel: driver is disconnected...
  if (iRun)        return (0);       // cancel: currently running...

  switch (vp->nItem)  {
    default:    return (0);
    case 0x00:  case 0x01:  case 0x02:  case 0x03:   // R0...R7
    case 0x04:  case 0x05:  case 0x06:  case 0x07:
      uRg.Rn [vp->nItem & 0x07] = pV->uc;
x:    SetRegs (&uRg);
      break;
    case 0x10: uRg.acc = pV->uc;  goto x;            // A
    case 0x11: uRg.b   = pV->uc;  goto x;            // B
    case 0x12: uRg.sp  = pV->uc;  goto x;            // SP
    case 0x13:
      uRg.dpl = (BYTE) pV->u16;
      uRg.dph = (BYTE) (pV->u16 >> 8);
      goto x;

    case 0x14:
      if (iRun) return (0);     // $ PC: can't change while running...
      uRg.nPC = (pV->ul & 0xFFFF) | (amCODE << 24);
      goto x;
//  case 0x15:                                // states, can't change
//  case 0x16:                                // sec, can't change
//    break;

    case 0x100:                               // PSW
      uRg.psw = pV->uc;
      goto x;

    case 0x101:                           // P
    case 0x102:                           // F1
    case 0x103:                           // OV
    case 0x104:                           // RS
    case 0x105:                           // F0
    case 0x106:                           // AC
    case 0x107:                           // Cy
      val = pV->uc;
      n   = vp->nItem - 0x101;            // use Item-number for index
      uRg.psw &= ~mx51[n].mask;           // clear value
      val = (val << mx51[n].shft) & mx51[n].mask;
      uRg.psw |= (BYTE) val;
      nRstat   = 1;                       // mark 'PSW' as curr

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -