📄 agdi.cpp
字号:
nErr = 0;
switch (nCode) { // which Opcode
case AG_READ: // read register
GetRegs(); // make sure REG51 is up to date
switch (nReg) {
case nnR0: case nnR1: case nnR2: case nnR3:
case nnR4: case nnR5: case nnR6: case nnR7:
pV->uc = REG51.Rn [nReg & 0x07];
break;
case nrA:
pV->uc = REG51.acc;
break;
case nrDPTR:
pV->u16 = (((WORD16) REG51.dph) << 8) | (WORD16) REG51.dpl;
break;
case mPC:
pV->u32 = REG51.nPC; // Note: requires 'amCODE << 24' selector.
break;
}
break;
case AG_WRITE:
switch (nReg) {
case nnR0: case nnR1: case nnR2: case nnR3:
case nnR4: case nnR5: case nnR6: case nnR7:
REG51.Rn [nReg & 0x07] = pV->uc;
x: SetRegs (®51);
break;
case nrA:
REG51.acc = pV->uc;
goto x;
case nrDPTR:
REG51.dpl = (BYTE) (pV->u16 & 0xFF);
REG51.dph = (BYTE) ((pV->u16 >> 8) & 0xFF);
goto x;
case mPC:
curPC = pV->u32;
WritePC (curPC); // to target
break;
}
break;
default:
nErr = AG_INVALOP; // invalid Operation
break;
}
if (PlayDead == 1) {
StopTarget();
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
return (nErr);
}
/*
* Memory Attribute access
*/
U32 _EXPO_ AG_MemAtt (U16 nCode, UL32 nAttr, GADR *pA) {
U16 nErr;
if (iRun && !supp.MemAccR) { // currently running, can't access.
return (AG_NOACCESS); // error: can't access memory
}
if (PlayDead) return (AG_NOACCESS);
nErr = 0;
switch (nCode) {
case AG_MEMMAP: // map memory address range
pA->ErrAdr = MMapMem (nAttr, pA->Adr, pA->nLen);
break;
case AG_GETMEMATT: // Attribute descriptor is requested
pA->Adr = (UL32) MGetAttr (pA->Adr); // so return it in pA->Adr.
break;
case AG_SETMEMATT: // not used by uVision.
break;
}
if (PlayDead) {
StopTarget();
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0); // terminate driver
}
return (nErr);
}
#define __BPQX (AG_ATR_BREAK | AG_ATR_BPDIS | AG_ATR_EXECD)
static UL32 MBpInfo (UL32 nAdr, U16 nCode) {
struct MMM acc;
U16 *pB;
UL32 nA, nSlot;
AG_BP *pK, *pN;
switch (nCode) {
case AG_BPDISALL: // disable all Exec-Bp's
case AG_BPKILLALL: // kill all Exec-Bp's
break;
default:
nSlot = SlotNo (nAdr); // requested code address
acc = mslots [nSlot];
if (acc.mem == NULL || acc.atr == NULL) {
return (0x80000000); // failed: unmapped address
}
pB = &acc.atr [nAdr & 0xFFFF];
break;
}
nA = 0;
switch (nCode) { // Function code
case AG_BPQUERY: // Query Break
case AG_BPEXQUERY: // Query for 'executed' attribute
nA = (UL32) (*pB & __BPQX); // Attributes are similar to uVision
break;
case AG_BPENABLE: // enable breakpoint
if (*pB & AG_ATR_BPDIS) { // is Bp disabled ?
*pB = (*pB & ~AG_ATR_BPDIS) | AG_ATR_BREAK; // enable it
break;
}
break;
case AG_BPDISABLE: // disable breakpoint
if (*pB & AG_ATR_BREAK) { // is Bp enabled ?
*pB = (*pB & ~AG_ATR_BREAK) | AG_ATR_BPDIS; // disable it
break;
}
break;
case AG_BPKILL: // kill breakpoint
*pB = *pB & ~(AG_ATR_BREAK | AG_ATR_BPDIS);
break;
case AG_BPSET: // Set breakpoint
*pB = (*pB & ~AG_ATR_BPDIS) | AG_ATR_BREAK;
break;
case AG_BPDISALL: // disable all Bp's
pK = *pBhead;
for ( ; pK ; pK = pK->next ) {
if (pK->type == AG_ABREAK && pK->enabled) {
++nA;
MBpInfo (pK->Adr, AG_BPDISABLE);
}
}
break;
case AG_BPKILLALL: // kill all Bp's
pK = *pBhead;
while (pK) {
pN = pK->next;
if (pK->type == AG_ABREAK) {
++nA;
MBpInfo (pK->Adr, AG_BPKILL);
}
pK = pN;
}
break;
}
return (nA);
}
int SaCBreaks (DWORD set, DWORD nA) { // 1:=set, 0:=clear
AG_BP *pB;
int nR;
abreaks = 0; // clear number of address Bp's
cbreaks = 0; // clear number of conditional Bp's
wbreaks = 0; // clear number of access Bp's
for ( pB = *pBhead ; pB ; pB = pB->next ) {
if (!pB->enabled) continue;
switch (pB->type) {
case AG_ABREAK: ++abreaks; break; // increase Nr. of AddressBreaks
case AG_CBREAK: ++cbreaks; break; // increase Nr. of CondBreaks
case AG_WBREAK: ++wbreaks; break; // increase Nr. of WatchBreaks
}
}
if (set == 0) { // Reset Breaks
if (SetBrkCount == 0) return (1);
--SetBrkCount;
}
else { // Set Breaks
if (SetBrkCount != 0) return (1);
++SetBrkCount;
}
//--- when CondBreaks or WatchBreaks are active, skip ExecBreaks
if (cbreaks || wbreaks) return (1);
nR = 1;
for ( pB = *pBhead ; pB ; pB = pB->next ) {
if (!pB->enabled) continue; // Break is disabled
switch (pB->type) {
case AG_ABREAK: // Addess-Break
if (pB->Adr == nA) { // g,main address
pBX = pB;
}
if (!SetClrBp (set, pB)) {
return (0);
}
break;
case AG_CBREAK: // Conditional-Break
break;
case AG_WBREAK: // Access-Break
break;
}
}
return (nR);
}
/*
* Is there a Breakpoint at address 'nAdr'
*/
DWORD IsBreak (DWORD nAdr) {
AG_BP *pB;
for ( pB = *pBhead ; pB ; pB = pB->next ) {
if (pB->enabled) {
if (pB->type == AG_ABREAK) {
if (pB->Adr == nAdr) {
return (1); // yes, 'nAdr' has a Bp on it
}
}
}
}
return (0);
}
/*
* Search for Breakpoint at address 'nAdr'
*/
DWORD BrkWalk (DWORD nAdr) {
AG_BP *pB;
for ( pB = *pBhead ; pB ; pB = pB->next ) {
if (!pB->enabled) continue; // this Break is disabled.
switch (pB->type) {
case AG_ABREAK: // Address Break
if (nAdr == pB->Adr) { // match
if (pB->rcount == 1) {
if (pB->cmd) { // is command defined
pCbFunc (AG_CB_EXECCMD, pB->cmd); // execute command
return (0); // continue app when command is defined
}
return (1); // don't continue app
}
--pB->rcount; // decrease counter
return (0); // continue app
}
break;
case AG_CBREAK: // Conditional Break, not supported
break;
case AG_WBREAK: // Watchpoint-Break, not supported
break;
}
}
return (2); // no break reason found
}
/*
* Breakpoint Management
*/
#define __BPQX (AG_ATR_BREAK | AG_ATR_BPDIS | AG_ATR_EXECD)
U32 _EXPO_ AG_BpInfo (U16 nCode, void *vp) {
U32 nA, nAdr;
U16 *pB;
AG_BP *pK;
if (PlayDead) return (0);
switch (nCode) {
case AG_BPDISALL: // disable all Exec-Bp's
case AG_BPKILLALL: // kill all Exec-Bp's
break;
default: // need attribute pointer anyway, set it up here.
nAdr = ((GADR *) vp)->Adr; // the referred address
pB = MGetAttr (nAdr); // get attribute location for 'nAdr'
if (!pB) return (0x80000000); // failed: unmapped address
break;
}
nA = 0;
switch (nCode) { // Function code
case AG_BPQUERY: // Query Break
case AG_BPEXQUERY: // Query for 'executed' attribute
nA = (UL32) (*pB & __BPQX); // Attributes are similar to uVision
break;
case AG_BPENABLE: // enable breakpoint
if (*pB & AG_ATR_BPDIS) { // is Bp disabled ?
*pB = (*pB & ~AG_ATR_BPDIS) | AG_ATR_BREAK; // enable it
}
break;
case AG_BPDISABLE: // disable breakpoint
if (*pB & AG_ATR_BREAK) { // is Bp enabled ?
*pB = (*pB & ~AG_ATR_BREAK) | AG_ATR_BPDIS; // disable it
break;
}
break;
case AG_BPKILL: // kill breakpoint
*pB = *pB & ~(AG_ATR_BREAK | AG_ATR_BPDIS);
break;
case AG_BPSET: // Set breakpoint
*pB = (*pB & ~AG_ATR_BPDIS) | AG_ATR_BREAK;
break;
case AG_BPDISALL: // disable all Bp's
pK = *pBhead; // head of breakpoint list
for ( ; pK ; pK = pK->next ) {
if (pK->type != AG_ABREAK || !pK->enabled) {
continue;
}
++nA; // count number of changed Bp's
pB = MGetAttr (pK->Adr); // get attribute location
if (pB && (*pB & AG_ATR_BREAK)) { // is Bp enabled ?
*pB = (*pB & ~AG_ATR_BREAK) | AG_ATR_BPDIS; // disable it
}
}
break;
case AG_BPKILLALL: // kill all Bp's
pK = *pBhead; // head of breakpoint list
for ( ; pK ; pK = pK->next ) {
if (pK->type != AG_ABREAK) continue;
++nA; // count number of changed Bp's
pB = MGetAttr (pK->Adr); // get attribute location
if (pB) {
*pB = *pB & ~(AG_ATR_BREAK | AG_ATR_BPDIS);
}
}
break;
}
if (PlayDead == 1) {
StopTarget();
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
return (nA);
}
_EXPO_ AG_BP *AG_BreakFunc (U16 nCode, U16 n1, GADR *pA, AG_BP *pBp) {
U16 *pB;
if (PlayDead) return (NULL); // driver is disconnected
if (nCode != 5) { // not BpAccept function
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -