📄 agdi.cpp
字号:
pB = MGetAttr (pA->Adr); // get attribute location
if (!pB) return (NULL); // invalid, cancel
}
switch (nCode) {
case 2: // Notification: 'pB' will be unlinked
*pB &= ~(AG_ATR_BREAK | AG_ATR_BPDIS);
break;
case 3: // not used.
case 6: // not used.
case 7: // not used.
case 8: // not used.
break;
case 1: // Notification: 'pB' will be linked
case 4: // 'pB->enabled' may have changed
if (pBp->enabled) {
*pB = (*pB & ~AG_ATR_BPDIS) | AG_ATR_BREAK; // enable it
}
else {
*pB = (*pB & ~AG_ATR_BREAK) | AG_ATR_BPDIS; // disable it
}
break;
case 5: // Bp-accept function
if (pBp->type == AG_WBREAK) { // read/write access Bp's are not supported here.
return (NULL);
}
break;
}
if (PlayDead == 1) {
StopTarget();
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
return (pBp);
}
static const char szGWW[] =
"Application does not run in real time because " \
"of conditional breakpoint(s) !\n";
/*
* Execute until 'nAdr' is reached or some other Bp fires.
*/
void GoUntil (DWORD nAdr) { // 0xFFFFFFFF := go forever
AG_BP abp;
pBX = NULL; // clear temporary Bp pointer.
if (StopRun) { // Stop-Button pressed
StopRun = 0;
return;
}
if (cbreaks || wbreaks) { // cond/watch break(s): need to single step
txtout ((char *) szGWW); // give the user a note about it.
}
else { // Go, setup Bp's first
if (IsBreak (curPC)) { // Bp at current PC, step over it.
Step();
}
if (!SaCBreaks (1, nAdr)) { // set breakpoints (1:=set, 0:=clear)
StopRun = 0; // write breakcode(s) failed.
return; // cancel Go
}
}
while (!StopRun) {
if (IsBreak (nAdr) || cbreaks || wbreaks) {
Step(); // One Step, then ReadPC()
Invalidate(); // registers, d/i-caches
if (BrkWalk (curPC) == 0x01) break;
if (IsBreak (curPC)) continue;
}
if (cbreaks || wbreaks) {
continue; // continue stepping with c/wbreaks
}
GoMode = 1;
abp.enabled = 0;
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.
}
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
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
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
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);
}
_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
/*
* Trace-History access function (future extension)
* Note: Trace is currently not supported when uVision2 is used with a target driver !
*/
_EXPO_ U32 AG_HistFunc (U32 nCode, I32 indx, I32 dir, void *vp) {
U32 nR = 0;
if (PlayDead) return (0);
#if 0 // TODO: Trace Recording Stuff
switch (nCode) {
case 0: // Function #0: get Hist index
break; // dir:=1 forward, dir:=0 backward
case 1: // Function #1: GetTracePC
break; // get PC of trace record 'indx'
case 2: // Function #2: GetHistRegs
break; // get recorded regs of record 'indx'
case 3: // Function #3: get Nr. of entries
break; // get number of instructions recorded so far
}
nR = HistFunc1 (nCode, indx, dir, (UC8 *) vp);
return (nR);
#endif
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 current.
goto x;
}
if (PlayDead == 1) { // target died for some reason...
StopTarget();
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0); // Asta la vista...
}
return (1); // Ok.
}
/*
* Initialize Register View
*/
static void InitRegs (void) {
REGDSC dsc;
dsc.nGitems = sizeof (rGroups) / sizeof (rGroups[0]);
dsc.nRitems = sizeof (rItems) / sizeof (rItems[0]);
dsc.GrpArr = rGroups;
dsc.RegArr = rItems;
dsc.RegGet = RegGet; // get function
dsc.RegSet = RegSet; // set function
pCbFunc (AG_CB_INITREGV, &dsc); // Install RegView in uVision2
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -