📄 rtxtiny.cpp
字号:
// RtxTiny.cpp : Defines the initialization routines for the DLL.
//
#include "stdafx.h"
#include "RtxTiny.h"
#include "..\Bom.h"
#include "..\AGDI.h"
#include "Rtx166T.h" // Rtx-166 Tiny Dialog
struct RtxSym RtxSym[] = { // i166
{ 0, "?RTX_TASKIDX", }, // word
{ 0, "?RTX_TASKIP", }, // word
{ 0, "?RTX_TASKCSP", }, // word, present in md/la/hla models
{ 0, "?RTX_STATE", }, // byte
{ 0, "?RTX_CURRENT", }, // byte
{ 0, "?RTX_TIMER", }, // word
{ 0, "?RTX_USRSP", }, // word
{ 0, "?RTX_SYSSP", }, // word
};
struct RtxSym RtxS51[] = { // i51
{ 0, "RTX_TASKIDX", },
{ 0, "RTX_TASKENTRY", },
{ 0, "?RTX_TASKSP", },
{ 0, "?RTX_TASKSTATUS", },
{ 0, "?RTX_CURRENTTASK", },
};
static const TYP tp_u8 = { bt_uchar, 1, 0, 0, 0, 0, 0, 0, };
static const TYP tp_u16 = { bt_uint, 2, 0, 0, 0, 0, 0, 0, };
DWORD RtxCur;
DWORD nTasks; // Number of RtxTiny-Tasks
TYR66 *pTasks; // Array of RtxTiny-Tasks
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//
// Note!
//
// If this DLL is dynamically linked against the MFC
// DLLs, any functions exported from this DLL which
// call into MFC must have the AFX_MANAGE_STATE macro
// added at the very beginning of the function.
//
// For example:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // normal function body here
// }
//
// It is very important that this macro appear in each
// function, prior to any calls into MFC. This means that
// it must appear as the first statement within the
// function, even before any object variable declarations
// as their constructors may generate calls into the MFC
// DLL.
//
// Please see MFC Technical Notes 33 and 58 for additional
// details.
//
/////////////////////////////////////////////////////////////////////////////
// CRtxTinyApp
BEGIN_MESSAGE_MAP(CRtxTinyApp, CWinApp)
//{{AFX_MSG_MAP(CRtxTinyApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRtxTinyApp construction
struct dbgblk *pdbg; // startup values
struct bom *pio; // Uv3's ioc structure
HANDLE hInst;
CRtx166t *pRtx;
static void InitRtx166Tiny (void) {
SYM *sp;
DWORD n1, n, i;
union v v;
TYR66 *pT;
if (pTasks != NULL) {
free (pTasks);
pTasks = NULL;
}
nTasks = 0;
for ( i = 0 ; i < (sizeof (RtxSym) / sizeof (RtxSym[0])) ; ++i ) {
sp = pio->FindPub (RtxSym[i].szN);
if (sp == NULL && i == 0) { // not an RTX-166 Tiny App !
return;
}
if (sp == NULL) RtxSym[i].nAdr = 0; // undefined
else RtxSym[i].nAdr = sp->v.ul; // address
}
pio->FetchItem (RtxSym[0].nAdr, (TYP *) &tp_u16, &v);
nTasks = v.u16 + 1; // Number of tasks
if (nTasks > 1024) nTasks = 1024;
pTasks = (TYR66 *) calloc ((nTasks + 1) * sizeof (TYR66), 1);
if (pTasks == NULL) { // calloc() failed.
nTasks = 0; // treat as 'non Rtx166-Tiny' App.
return;
}
pT = pTasks;
for ( n = 0 ; n < nTasks ; ++n, ++pT ) {
pT->n = (BYTE) n; // internal task number
n1 = RtxSym[1].nAdr + (n * 2); // ?RTX_TASKIP for task n
pio->FetchItem (n1, (TYP *) &tp_u16, &v);
pT->nAdr = v.u16; // Address Low
if (RtxSym[2].nAdr != 0) { // Segment is present
pio->FetchItem (RtxSym[2].nAdr + (n * 2), (TYP *) &tp_u16, &v);
pT->nAdr |= (v.ul << 16); // Address High
}
pT->sp = pio->PubSymByVal (pT->nAdr, F66_LOC);
}
}
static void InitRtx51Tiny (void) {
SYM *sp;
DWORD n1, n, i;
union v v;
TYR66 *pT;
if (pTasks != NULL) {
free (pTasks);
pTasks = NULL;
}
nTasks = 0;
for ( i = 0 ; i < (sizeof (RtxS51) / sizeof (RtxS51[0])) ; ++i ) {
sp = pio->FindPub (RtxS51[i].szN);
if (sp == NULL && i == 0) { // not an RTX-51 Tiny App !
return;
}
if (sp == NULL) RtxS51[i].nAdr = 0; // undefined
else RtxS51[i].nAdr = sp->v.ul; // address
}
pio->FetchItem (RtxS51[0].nAdr, (TYP *) &tp_u8, &v);
nTasks = v.uc + 1; // Number of tasks
//if (nTasks > 1024) nTasks = 1024;
pTasks = (TYR66 *) calloc ((nTasks + 1) * sizeof (TYR66), 1);
if (pTasks == NULL) { // calloc() failed.
nTasks = 0; // treat as 'non Rtx51-Tiny' App.
return;
}
pT = pTasks;
for ( n = 0 ; n < nTasks ; ++n, ++pT ) {
pT->n = (BYTE) n; // internal task number
n1 = RtxS51[1].nAdr + (n * 2); // &?RTX_TASKENTRY + i*2
pio->FetchItem (n1, (TYP *) &tp_u16, &v);
pT->nAdr = v.u16 | (mmCODE << 16); // C:0xnnnn
pT->sp = pio->PubSymByVal (pT->nAdr, F66_LOC);
}
}
static void InitRtx (void) {
switch (pio->iMCS) {
case iMCS166:
InitRtx166Tiny();
break;
case iMCS51:
InitRtx51Tiny();
break;
case iMCS251:
break;
}
}
void RtxUpd (void) { // Update Function
switch (pio->iMCS) {
case iMCS251:
break;
case iMCS51:
case iMCS166:
if (pRtx) pRtx->Update();
break;
}
}
void RtxKill (DLGD *pM) { // Kill Function
switch (pio->iMCS) {
case iMCS251:
break;
case iMCS51:
case iMCS166:
if (pRtx == NULL) break;
pRtx->SendMessage (WM_CLOSE);
pRtx = NULL;
break;
}
if (pTasks != NULL) {
free (pTasks);
pTasks = NULL;
}
nTasks = 0;
pM->iOpen = 0;
pM->hw = NULL;
}
void RtxDisp (DYM *pM) {
if (pM->pDlg->hw != NULL) { // created
RtxKill (pM->pDlg); // close
}
else {
// AFX_MANAGE_STATE(AfxGetStaticModuleState()); -- not necessary.
if (nTasks == 0) {
InitRtx(); // Cache some Rtx166-Tiny data
}
switch (pio->iMCS) {
case iMCS51:
case iMCS166:
pRtx = new CRtx166t (pM, NULL); // modeless construction
if (pRtx != NULL) { // construction was Ok.
pM->pDlg->hw = pRtx->m_hWnd; // Dialog handle
}
break;
case iMCS251:
break;
}
}
}
DLGD RtxDlg[] = { // must not use 'const' here !
//iOpen Hwnd Dlg Proc. Rect: -1 := default Update Kill
{ 0, NULL, NULL, { -1, -1, -1, -1, }, RtxUpd, RtxKill },
};
DYM RtxMenu[] = {
{ 1, "&Rtx-Tiny Tasklist", RtxDisp, 0,IDD_RTXTINY,&RtxDlg[0], },
{ -1, NULL , NULL, 0, 0, 0, }, // EoMenu
};
static void RtxUpdate (DWORD nCode) {
DYM *pM;
switch (nCode) {
case 1: // ReInit after Load-File.
InitRtx(); // Reload cached Rtx data
// continue with update.
case 0: // Update
pM = &RtxMenu[0];
while (1) {
if (pM->nDelim == -1) break; // end ofMenu list
if (pM->pDlg && pM->pDlg->hw) { // Dialog is visible
pM->pDlg->Update(); // update contents
}
++pM;
}
break;
}
}
/*
* Global Rtx166-Tiny 'DWORD _TaskRunning_ (u32)' function
*/
static DWORD RtxTaskRun (union v *pV) {
DWORD nE, nA;
DWORD RtxC, i;
TYR66 *pT;
union v v;
if (nTasks == 0 || pTasks == NULL) goto x; // no tasks at all.
nE = pio->FetchItem (RtxSym[4].nAdr, (TYP *) &tp_u8, &v); // fetch ?rtx_current
if (nE == 0) goto x; // Memory-access failed, say no.
RtxC = v.ul & 0xFF; // TaskNo of current Task
pT = pTasks;
for ( i = 0 ; i < nTasks ; ++i, ++pT ) {
if (pT->nAdr == pV->ul) { // found task by address
if (pT->n != RtxC) break; // v.ul is not current task
nA = RtxSym[3].nAdr + pT->n;
nE = pio->FetchItem (nA, (TYP *) &tp_u8, &v); // fetch ?rtx_state[TaskNo]
if (nE == 0) goto x; // access failed.
nE = (v.uc & 0x20) ? 1 : 0; // check running bit
return (nE);
}
}
x:
return (0);
}
/*
* Global Rtx51-Tiny 'DWORD _TaskRunning_ (u32)' function
*/
static DWORD RtxTaskR51 (union v *pV) {
DWORD nE, nA;
DWORD RtxC, i;
TYR66 *pT;
union v v;
if (nTasks == 0 || pTasks == NULL) goto x; // no tasks at all.
nE = pio->FetchItem (RtxS51[4].nAdr, (TYP *) &tp_u8, &v); // fetch ?rtx_current
if (nE == 0) goto x; // Memory-access failed, say no.
RtxC = v.ul & 0xFF; // TaskNo of current Task
pT = pTasks;
for ( i = 0 ; i < nTasks ; ++i, ++pT ) {
if (pT->nAdr == pV->ul) { // found task by address
if (pT->n != RtxC) break; // v.ul is not current task
nA = RtxS51[3].nAdr + (pT->n * 2) + 1; // &?RTX_TASKSTATUS+i*2+1
nE = pio->FetchItem (nA, (TYP *) &tp_u8, &v); // fetch ?rtx_state[TaskNo]
if (nE == 0) goto x; // access failed.
nE = (v.uc & 0x10) ? 1 : 0; // check running bit
return (nE);
}
}
x:
return (0);
}
extern "C" int EXPRT BootDll (DWORD nCode, void *p1) {
DYM *pM;
switch (nCode) {
case 1: // init ioc
nTasks = 0; // clear some local variables
pTasks = NULL;
pio = (struct bom *) p1;
if (pio->nSize != sizeof (ioc)) {
return (-2);
}
pio->pMrtx = &RtxMenu[0]; // Menu-Array
pio->RtxUpdate = RtxUpdate; // Update function
switch (pio->iMCS) {
case iMCS166:
pio->TaskRun = RtxTaskRun; // 166 _TaskRunning_ function
break;
case iMCS51:
pio->TaskRun = RtxTaskR51; // 51 _TaskRunning_ function
break;
case iMCS251:
pio->TaskRun = NULL; // 251 _TaskRunning_ function
break;
}
return (1); // Ok.
break;
case 2: // unused function code
return (1);
case 3: // Init our dll
pdbg = (struct dbgblk *) p1; // autoboot parameters
// MainArgs (pdbg->MainArgs); // analyze arguments
return (1);
case 4: // Shut down DLL
if (pTasks) free (pTasks);
pTasks = NULL;
nTasks = 0;
pM = &RtxMenu[0];
while (pM->nDelim != -1) { // close all open dialogs
if (pM->pDlg) { // Dialog is still open
pM->pDlg->iOpen = 0;
if (pM->pDlg->hw) {
pM->pDlg->Kill(pM->pDlg);// so close it
pM->pDlg->iOpen = 1; // auto reopen next time
}
}
++pM;
}
pio->pMrtx = NULL; // detach RTX menu items
pio->TaskRun = NULL; // clear _TaskRunning_ function
return (1); // Ok.
}
return (0);
}
// It is nice to be able to make a DLL project that includes
// its own resources (such as a dialog resource) and then be
// able to call it from another project. Seems simple but I
// went nuts until I found out the following:
// In the DLL function that pops up the dialog you must manage
// the state so that the DLL code uses the DLL's resources.
#if 0
extern __declspec(dllexport) void ShowEditDialog(int &MyData1, int &MyData2)
{
//ensure we are using our own resources
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CMyLocalDialog dlg;
dlg.Arg1 = MyData1; //specific local data for MyLocalDialog
dlg.Arg2 = MyData2;
dlg.DoModal();
MyData1 = dlg.Arg1; //data after processing
MyData2 = dlg.Arg2;
}
#endif
CRtxTinyApp::CRtxTinyApp() {
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CRtxTinyApp object
// Note: 'theApp' is required although it doesn't use an App object.
// If 'theApp' is missing, then each Dialog shows up in the TaskBar !
CRtxTinyApp theApp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -