📄 agdi.cpp
字号:
#include "stdafx.h"
#include "SampTarg.h"
#define _IN_TARG_ // define if used within target
#include "Agdi.h"
#include "Bom.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)
BYTE FlashProg; // Debugger started in Flash Programming mode
static OIL ProgressBar; // Progress-Bar data
int NumRecs; // number of trace records
/*
* 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
int FlashLoad (void); // forward
/*
* Initialize uVision2 Progress bar
*/
static void InitProgress (char *msg) {
ProgressBar.Job = PROGRESS_INIT;
ProgressBar.pos = 0;
ProgressBar.low = 0;
ProgressBar.hig = 100;
ProgressBar.label = (SC8 *)msg;
pCbFunc (AG_CB_PROGRESS, &ProgressBar);
}
/*
* Kill uVision2 Progress bar
*/
static void StopProgress (void) {
ProgressBar.Job = PROGRESS_KILL;
pCbFunc (AG_CB_PROGRESS, &ProgressBar);
}
/*
* Set Progress bar
*/
static void SetProgress (DWORD pos ) {
if (pos > 100) pos = 100;
ProgressBar.Job = PROGRESS_SETPOS;
ProgressBar.pos = pos;
pCbFunc (AG_CB_PROGRESS, &ProgressBar);
}
//--- Memory cache handling.
//--- Simulate the (non-existing) target memory
// Memory caching is used to increase debugger performance.
// When uVision2 requests data, it is taken out from cache memory buffer
// instead of reading it from the target hardware. This performance
// is increased slightly if fast interface is used (USB, Ethernet,...)
struct MMM mslots [520]; // cache memory slots
/*
* Free all allocated memory by this driver before driver shutdown.
*/
static void FreeCache (void) {
struct MMM *s;
int i;
for ( i = 0 ; i < (sizeof (mslots) / sizeof (mslots[0])) ; ++i ) {
s = &mslots [i]; // a16-a23
if (s->mem) {
free (s->mem);
free (s->atr);
s->mem = NULL;
s->atr = NULL;
}
}
//---TODO: free additional memory resources, if allocated
}
/*
* 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);
}
/*
* 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);
switch (nAdr >> 24) {
case amDATA:
if ((nAdr & 0xFF) < 0x80) break; // Cache internal DATA
return (0); // SFRs are not cached
case amIDATA: // Cache DATA, IDATA
if (MonConf.Opt & CACHE_DATA) break;
return (0);
case amXDATA: // Cache XDATA ram
if (MonConf.Opt & CACHE_XDATA) break;
return (0);
case amCODE: // Cache CODE mem.
if (MonConf.Opt & CACHE_CODE) break;
return (0);
}
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) {
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;
}
}
/*
* 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 address '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 InitMem (void) {
MapSeg (amDATA, 0x00, 0x100, AG_ATR_READ | AG_ATR_WRITE);
MapSeg (amIDATA, 0x80, 0x80, AG_ATR_READ | AG_ATR_WRITE);
MapSeg (amXDATA, 0x0000, 0x10000, AG_ATR_READ | AG_ATR_WRITE);
MapSeg (amCODE, 0x0000, 0x10000, AG_ATR_READ | AG_ATR_EXEC);
//---TODO:
//---add cache buffer for additional memory space here if needed
}
//--- End of c/i-chache
/*
* Output a message line into uVision2's command window in debug mode
* and to build window in Flash download mode
*/
void txtout (char *fmt, ...) {
va_list marker;
char txtbuf [2048];
va_start (marker, fmt);
vsprintf (&txtbuf[0], fmt, marker);
SendMessage (hMfrm, // for Flash Download send message to Build window
Uv2Msg, FlashProg ? MSG_UV2_TRNLINE : MSG_UV2_CMDLINE,
(LPARAM) &txtbuf[0]);
}
/*
* This function is required for Remote-Setup in uVision2 Debug mode
*/
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, 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -