📄 agdi.cpp
字号:
}
break;
case amIDATA:
if (((nAdr & 0xFF) + n) > 0x100) n1 = 0x100 - (nAdr & 0xFF);
else n1 = n;
ErrAdr = WriteIdata (pB, nAdr & 0xFF0000FF, n1);
break;
// case amCODE:
default:
ErrAdr = WriteCode (pB, nAdr, n);
break;
}
pB += n;
nAdr += n;
}
if (ErrAdr == 0) { // write was Ok.
CacheData (p1, nA, nM); // put write data into cache
}
else { // write failed...
ClearCaR (nA, nM); // invalidate cache range
}
return (ErrAdr);
}
/*
* Access target memory
*/
U32 _EXPO_ AG_MemAcc (U16 nCode, UC8 *pB, GADR *pA, UL32 nMany) {
U16 nErr;
UL32 nA;
if (iRun && !supp.MemAccR) { // currently running, can't access.
return (AG_NOACCESS); // error: can't access register
}
if (PlayDead) { // driver disconnected.
return (AG_NOACCESS);
}
nErr = 0;
if (hMfrm == NULL) return (nErr);
nA = pA->Adr;
switch (nCode) {
case AG_READ: // need 'read' permission
pA->ErrAdr = ReadMem (nA, pB, nMany);
if (pA->ErrAdr) nErr = AG_RDFAILED;
break;
case AG_WRITE: // need 'write' permission
pA->ErrAdr = WriteMem (nA, pB, nMany);
if (pA->ErrAdr) nErr = AG_WRFAILED;
break;
// used for Program download
case AG_WROPC: // need 'Read/Execute' permissions
nA |= (amCODE << 24);
pA->ErrAdr = WriteMem (nA, pB, nMany);
if (pA->ErrAdr) nErr = AG_WRFAILED;
break;
// used for disassembly etc.
case AG_RDOPC: // need 'Read/Execute' permissions
nA |= (amCODE << 24);
pA->ErrAdr = ReadMem (nA, pB, nMany);
if (pA->ErrAdr) nErr = AG_RDFAILED;
break;
default:
nErr = AG_INVALOP; // invalid Operation
break;
}
if (PlayDead == 1) { // disconnected...
StopTarget(); // shut down driver
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
return (nErr);
}
/*
* Read/Write Registers
*/
U32 _EXPO_ AG_AllReg (U16 nCode, void *vp) {
U16 nErr;
if (iRun && !supp.RegAccR) { // currently running, can't access.
return (AG_NOACCESS); // error: can't access register
}
if (PlayDead) return (AG_NOACCESS);
nErr = 0;
switch (nCode) { // which Opcode
case AG_READ: // read register
GetRegs();
break;
case AG_WRITE:
SetRegs (®51); // write Regs + PC
RegUpToDate = 1; // mark regs as 'up to date'
break;
default:
nErr = AG_INVALOP; // invalid Operation
break;
}
if (PlayDead == 1) {
StopTarget();
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
return (nErr);
}
/*
* Read/Write a single Register
*/
U32 _EXPO_ AG_RegAcc (U16 nCode, U32 nReg, GVAL *pV) {
U16 nErr;
if (iRun && !supp.RegAccR) { // currently running, can't access.
return (AG_NOACCESS); // error: can't access register
}
if (PlayDead) return (AG_NOACCESS); // driver is disconnected.
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);
}
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
}
#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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -