📄 agdi.cpp
字号:
#include "stdafx.h"
#include "SampTarg.h"
#define _IN_TARG_ // define if used within target
#include "Agdi.h"
#include "ComTyp.h"
#include "Collect.h"
#include <stdio.h>
#include "resource.h"
RG51 REG51; // 8051 Registers
BYTE initflag;
BYTE bootflag;
BYTE PlayDead; // Disables the driver after comm breaks down.
BYTE RegUpToDate; // Flag: mark driver is 'dead' (disconnected)
/*
* AGDI-Data
*/
SUPP supp; // supported features
UC8 iRun; // target is currently executing
UC8 StopRun; // Flag: stop execution
UC8 GoMode;
AG_BP **pBhead;
UL32 *pCURPC;
UL32 curPC;
AG_BP *pBX; // used for temporary Breakpoint
UL32 abreaks; // number of code-address Bp's
UL32 cbreaks; // number of conditional Bp's
UL32 wbreaks; // number of access Bp's
UL32 SetBrkCount;
static const char szNBP[] = "*** AGDI-Error: can't setup break at 0x%08X\n";
UL32 Uv2Msg; // Uv2-registered Message token
pCBF pCbFunc; // call-back function of s166
extern DYMENU Menu[]; // forward
// if an extension modeless dialog is activated, then '*pHwnd' *MUST*
// receive the HWND (m_hWnd in MFC) of the dialog. If the dialog
// looses focus or is closed, then '*pHwnd' *MUST* be set to NULL.
// This is to ensure the proper message chain within Uv2.
HWND *pHwnd;
HWND hMfrm; // parent handle (CMainFrame)
HMODULE hInst; // this DLL's instance handle
extern void InitRegs (void); // forward
//--- Memory cache handling.
//--- Simulate the (non-existing) target memory
struct MMM mslots [520]; // code: 0x000...0x0FF (max. 16MB)
// xdata: 0x100...0x1FF (max. 16MB)
// sfr: 0x200
// idata: 0x201
// remaining slots reserved for future use.
/*
* free any allocated memory before driver shutdown.
* Note: mslots[] must not be free'd by our driver.
*/
static void FreeCache (void) {
//---TODO: free memory resources, if any
}
/*
* Map full address to Cache-Slot-number:
*/
static DWORD SlotNo (DWORD n) {
DWORD z;
switch (n >> 24) { // high byte of address holds mSpace.
case amDATA:
if ((n & 0xFF) >= 0x80) { // SFR-address
n = 0x200; // sfr slot at 0x200
break;
}
case amIDATA:
n = 0x201; // idata slot at 0x201
break;
case amPDATA:
case amXDATA:
n = 0x100 + ((n >> 16) & 0xFF); // xdata slots start at 0x0100
break;
default: // code
z = (n >> 16) & 0xFF;
if (z >= amBANK0 && z <= amBANK31) {
n = z; // banking: slots 0x80...0x9F
}
else { // code slot (0x00...0xFF)
n = z;
}
break;
}
return (n);
}
/*
* deletes the AG_ATR_UPTD attribute bit in all mapped memory areas
*/
void InvalCache (void) {
int i, k;
struct MMM *pM;
//---Note: code slots 0x00...0xFF are not invalidated.
//---invalidate xdata memory:
for ( i = 0x100 ; i < 0x200 ; ++i ) { // invalidate xdata slots
pM = &mslots [i];
if (!pM->mem) continue; // not mapped
for ( k = 0 ; k < 0x10000 ; ++k ) { // these segs are 64K each
pM->atr [k] &= ~AG_ATR_UPTD; // clear 'data valid' bit
}
}
//---invalidate sfr memory:
pM = &mslots [0x200]; // SFR slot
for ( k = 0x80 ; k < 0x100 ; ++k ) { // just 128 bytes d:0x80...d:0xff
pM->atr [k] &= ~AG_ATR_UPTD; // clear 'data valid' bit
}
//---invalidate idata memory:
pM = &mslots [0x201]; // idata slot
for ( k = 0 ; k < 0x100 ; ++k ) { // i:0x00...i:0xFF
pM->atr [k] &= ~AG_ATR_UPTD; // clear 'data valid' bit
}
}
/*
* Cache data
*/
void CacheData (BYTE *pB, DWORD nAdr, DWORD nCnt) {
U16 *pA;
BYTE *pM;
DWORD nSlot, aMask;
if (pB == NULL || nCnt == 0) return;
for ( ; nCnt != 0 ; --nCnt, ++nAdr, ++pB ) {
nSlot = SlotNo (nAdr);
switch (nAdr >> 24) {
case amDATA:
case amPDATA:
case amIDATA:
aMask = 0xFF;
break;
default:
aMask = 0xFFFF;
break;
}
pA = mslots [nSlot].atr;
pM = mslots [nSlot].mem;
if (!pA || !pM) continue; // both of them need to be valid
pA [nAdr & aMask] |= AG_ATR_UPTD; // 'up to date' attribute
pM [nAdr & aMask] = *pB; // the data
}
}
/*
* clear 'AG_ATR_UPDT' for the given range
*/
void ClearCaR (DWORD nAdr, DWORD nCnt) {
U16 *pA;
DWORD nSlot, aMask;
for ( ; nCnt != 0 ; --nCnt, ++nAdr ) {
nSlot = SlotNo (nAdr);
switch (nAdr >> 24) {
case amDATA:
case amPDATA:
case amIDATA:
aMask = 0xFF;
break;
default:
aMask = 0xFFFF;
break;
}
pA = mslots [nSlot].atr;
if (pA != NULL) { // attributes are valid.
pA [nAdr & aMask] &= ~AG_ATR_UPTD; // clear 'up to date' attribute
}
}
}
/*
* Check if chached data is valid.
*/
int CacheValid (BYTE *pB, DWORD nAdr, DWORD nCnt) {
int n1, n2;
U16 *pA;
BYTE *pM;
DWORD nSlot,aMask;
if (pB == NULL) return (0);
#if 0 // if 'CACHE_CODE' is implemented in target-setup...
if ((nAdr >> 24) == amCODE) { // access code
if (!(MonConf.Opt & CACHE_CODE)) { // caching is off,
return (0); // cancel looking into cache.
}
}
#endif
#if 0 // if 'CACHE_MEM' is implemented in target-setup...
else {
if (!(MonConf.Opt & CACHE_MEM)) {
return (0); // read caching is off
}
}
#endif
n1 = nCnt;
for ( n2 = 0 ; n1 != 0 ; ++n2, --n1, ++nAdr ) {
nSlot = SlotNo (nAdr);
switch (nAdr >> 24) {
case amDATA:
case amPDATA:
case amIDATA:
aMask = 0xFF;
break;
default:
aMask = 0xFFFF;
break;
}
pA = mslots [nSlot].atr;
pM = mslots [nSlot].mem;
if (!pA || !pM) return (0); // both of them need to be valid
if (!(pA [nAdr & aMask] & AG_ATR_UPTD)) {
return (0); // cache data invalid.
}
pB [n2] = pM [nAdr & aMask]; // copy data to user buffer
}
return (1); // cached data valid.
}
/*
* Map Memory
*/
static void MapSeg (DWORD nSeg, DWORD nSof, DWORD nLen, WORD16 nAtr) {
nSeg;
nSof;
nLen;
nAtr;
#if 0
struct MMM *s;
WORD16 *pA;
DWORD n;
if (nLen == 0) return;
n = SlotNo (nSeg);
s = &mslots [n];
if (s->mem == NULL) { // if not already mapped...
s->mem = (UC8 *) calloc (_MSGM, 1); // allocate 64k block
s->atr = (U16 *) calloc (_ASGM, 1); // and associated attributes
if (s->mem == NULL || s->atr == NULL) { // malloc failed.
s->mem = NULL;
s->atr = NULL;
return;
}
}
pA = &s->atr [nSof];
for ( n = 0 ; n < nLen ; ++n, ++pA ) { // initialize attribs
*pA &= (AG_ATR_READ | AG_ATR_WRITE | AG_ATR_EXEC | AG_ATR_EXTR | AG_ATR_UPTD);
*pA |= nAtr;
}
#endif
}
/*
* Map a cache segment descriptor.
*/
DWORD MMapMem (UL32 nAtr, UL32 nAdr, UL32 nLen) {
if (nAtr == 0) {
nAtr = AG_ATR_READ | AG_ATR_WRITE | AG_ATR_EXEC;
}
MapSeg (nAdr, nAdr & 0xFFFFFF, nLen, (U16) nAtr);
return (0);
}
/*
* Get Pointer to Attribute Segment for address 'nAdr'
*/
U16 *MGetAttrSeg (UL32 nAdr) {
U16 *pA;
DWORD n;
n = SlotNo (nAdr); // map address to cache slot
pA = mslots [n].atr; // and return the attribute segment.
return (pA);
}
/*
* Get Pointer to Attributes for addresss 'nAdr'
*/
U16 *MGetAttr (UL32 nAdr) {
U16 *pA;
pA = MGetAttrSeg (nAdr); // get attribute segment
if (pA != NULL) {
pA = &pA [nAdr & 0xFFFF]; // address of attributes for address 'nAdr'
}
return (pA);
}
void WriteAttr (UL32 nAdr, UL32 aMask, UL32 oMask, UL32 nMany) {
U16 *pA;
for ( ; nMany != 0 ; --nMany, ++nAdr ) {
pA = MGetAttrSeg (nAdr);
if (pA == NULL) continue;
*pA &= ~aMask;
*pA |= oMask;
}
}
static void InitCache (void) {
}
//--- End of c/i-chache
/*
* Output a message line into uVision2's command window
*/
void txtout (char *fmt, ...) {
va_list marker;
char txtbuf [2048];
va_start (marker, fmt);
vsprintf (&txtbuf[0], fmt, marker);
SendMessage (hMfrm, Uv2Msg, MSG_UV2_CMDLINE, (LPARAM) &txtbuf[0]);
}
/*
* Show target setup dialog
*/
static void ConfDisp (DYMENU *pM) {
struct MonConf oCnf;
int i;
pM;
oCnf = MonConf; // save current setup
i = DoDlgSetup(); // start setup dialog
if (i == IDOK) {
if (memcmp (&MonConf, &oCnf, sizeof (oCnf)) != 0) { // configuration has changed
i = MessageBox (hMfrm,"Configuration has been changed, take new values ?",
"Target Monitor Notification",
MB_OKCANCEL | MB_ICONWARNING);
if (i == IDCANCEL) {
MonConf = oCnf; // restore previous configuration
}
if (i == IDOK) { // take new configuration
if (ReInitTarget()) { // failed...
StopTarget(); // final shutdown
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
}
}
}
else { // cancelled: restore previous config
MonConf = oCnf;
}
}
/*
* Extension Menues and Dialogs
*/
//--- this relates to TestDlg.cpp: ------------
extern void MdUpdate (void); // Dialog Update function
extern void MdKill (DIAD *pM); // Dialog Kill function
extern void MdShow (DYMENU *pM); // Show/Hide modeless Dialog
DIAD ModDlg = { 0, NULL, NULL, { -1,-1,-1,-1, }, MdUpdate, MdKill };
//---------------------------------------------
static DYMENU Menu[] = {
{ 1, "Target Settings", ConfDisp, 0, 0, }, // modal dialog
{ 1, "Modeless Dialog", MdShow, 0, 0, &ModDlg }, // modeless dialog
{ -1, /* End of menu list */ },
};
/*
* uVision2 want's to update all modeless dialogs.
*/
void DlgUpdate (void) { // Update all modeless extension dialogs
DYMENU *pM;
pM = &Menu[0];
while (pM->nDelim != -1) { // while not end of Menu-list
if (pM->pDlg && pM->pDlg->Update) { // if dialog has been created
pM->pDlg->Update(); // then call it's update function
}
++pM; // next menu entry.
}
}
/*
* Need to close all currently open modeless dialogs
*/
void CloseAllDlg (void) {
DYMENU *pM;
pM = &Menu[0];
while (pM->nDelim != -1) {
if (pM->pDlg && pM->pDlg->hw) { // Dialog is visible
pM->pDlg->Kill (pM->pDlg); // update contents
}
++pM;
}
}
//--- Interface functions between AGDI and target follow
//------------------------------------------------------
/*
* Read 'nMany' bytes out of data space into buffer 'pB'
* return: 0:=Ok, else 'ErrorAddress | (amDATA << 24)'
*/
UL32 ReadData (BYTE *pB, DWORD nAdr, DWORD nMany) {
if (CacheValid (pB, nAdr, nMany)) { // use cache, if possible
return (0);
}
//---TODO:
//---if Ok, then return 0, else error-address
// adr |= (amDATA << 24); // make address uVision2 conforming
return (0); // say Ok.
}
/*
* Read 'nMany' bytes out of the idata space into buffer 'pB'
* return: 0:=Ok, else 'ErrorAddress | (amIDATA << 24)'
*/
UL32 ReadIdata (BYTE *pB, DWORD nAdr, DWORD nMany) {
if (CacheValid (pB, nAdr, nMany)) { // use cache, if possible
return (0);
}
//---TODO:
//---if Ok, then return 0, else error-address
// adr |= (amIDATA << 24); // make address uVision2 conforming
return (0); // say Ok.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -