emu48-mirror/Sources/Emu48/DDESERV.C

171 lines
4.8 KiB
C
Raw Normal View History

2024-03-19 22:24:30 +01:00
/*
* DdeServ.c
*
* This file is part of Emu48
*
* Copyright (C) 1998 Christoph Gie<EFBFBD>elink
*
*/
#include "pch.h"
#include "Emu48.h"
2024-03-19 22:37:54 +01:00
#include "io.h"
2024-03-19 22:24:30 +01:00
HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
HSZ hsz1,HSZ hsz2,HDDEDATA hData,
DWORD dwData1,DWORD dwData2)
{
TCHAR *psz,szBuffer[32];
2024-03-19 22:24:30 +01:00
HDDEDATA hReturn;
2024-03-19 22:25:45 +01:00
LPBYTE lpData,lpHeader;
2024-03-19 22:24:30 +01:00
DWORD dwAddress,dwSize,dwLoop,dwIndex;
UINT nStkLvl;
2024-03-19 22:24:30 +01:00
BOOL bSuccess;
2024-03-19 22:38:33 +01:00
// disable stack loading items on HP38G, HP39/40G
BOOL bStackEnable = cCurrentRomType!='6' && cCurrentRomType!='A' && cCurrentRomType!='E';
2024-03-19 22:24:30 +01:00
switch (iType)
{
case XTYP_CONNECT:
// get service name
2024-03-19 22:37:03 +01:00
DdeQueryString(idDdeInst,hsz2,szBuffer,ARRAYSIZEOF(szBuffer),0);
if (0 != lstrcmp(szBuffer,szAppName))
2024-03-19 22:24:30 +01:00
return (HDDEDATA) FALSE;
// get topic name
2024-03-19 22:37:03 +01:00
DdeQueryString(idDdeInst,hsz1,szBuffer,ARRAYSIZEOF(szBuffer),0);
return (HDDEDATA) (INT_PTR) (0 == lstrcmp(szBuffer,szTopic));
2024-03-19 22:24:30 +01:00
case XTYP_POKE:
// quit on models without stack or illegal data format or not in running state
if (!bStackEnable || iFmt != uCF_HpObj || nState != SM_RUN)
2024-03-19 22:24:30 +01:00
return (HDDEDATA) DDE_FNOTPROCESSED;
// get item name
DdeQueryString(idDdeInst,hsz2,szBuffer,ARRAYSIZEOF(szBuffer),0);
nStkLvl = _tcstoul(szBuffer,&psz,10);
if (*psz != 0 || nStkLvl < 1) // invalid number format
return (HDDEDATA) DDE_FNOTPROCESSED;
2024-03-19 22:24:30 +01:00
DdeAccessData(hData,&dwSize); // fetch data size
DdeUnaccessData(hData);
// reserve memory
2024-03-19 22:38:33 +01:00
if ((lpData = HeapAlloc(hHeap,0,dwSize * 2)) == NULL)
2024-03-19 22:24:30 +01:00
return (HDDEDATA) DDE_FNOTPROCESSED;
2024-03-19 22:38:33 +01:00
SuspendDebugger(); // suspend debugger
bDbgAutoStateCtrl = FALSE; // disable automatic debugger state control
2024-03-19 22:37:54 +01:00
if (!(Chipset.IORam[BITOFFSET]&DON)) // HP off
2024-03-19 22:24:30 +01:00
{
// turn on HP
KeyboardEvent(TRUE,0,0x8000);
KeyboardEvent(FALSE,0,0x8000);
}
2024-03-19 22:25:45 +01:00
if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state
2024-03-19 22:24:30 +01:00
{
2024-03-19 22:38:33 +01:00
HeapFree(hHeap,0,lpData); // free memory
hReturn = DDE_FNOTPROCESSED;
goto cancel;
2024-03-19 22:24:30 +01:00
}
while (nState!=nNextState) Sleep(0);
2024-03-19 22:37:03 +01:00
_ASSERT(nState==SM_SLEEP);
2024-03-19 22:24:30 +01:00
// fetch data and write to stack
DdeGetData(hData,(LPBYTE) &dwIndex,sizeof(DWORD),0L);
if (dwIndex <= dwSize - sizeof(DWORD))
dwSize = dwIndex;
dwSize = DdeGetData(hData,lpData+dwSize,dwSize,sizeof(DWORD));
bSuccess = (WriteStack(nStkLvl,lpData,dwSize) == S_ERR_NO);
2024-03-19 22:38:33 +01:00
HeapFree(hHeap,0,lpData); // free memory
2024-03-19 22:24:30 +01:00
2024-03-19 22:37:03 +01:00
SwitchToState(SM_RUN); // run state
2024-03-19 22:24:30 +01:00
while (nState!=nNextState) Sleep(0);
2024-03-19 22:37:03 +01:00
_ASSERT(nState==SM_RUN);
2024-03-19 22:24:30 +01:00
if (bSuccess == FALSE)
2024-03-19 22:38:33 +01:00
{
hReturn = DDE_FNOTPROCESSED;
goto cancel;
}
2024-03-19 22:24:30 +01:00
KeyboardEvent(TRUE,0,0x8000);
Sleep(200);
2024-03-19 22:24:30 +01:00
KeyboardEvent(FALSE,0,0x8000);
// wait for sleep mode
while (Chipset.Shutdn == FALSE) Sleep(0);
2024-03-19 22:38:33 +01:00
hReturn = (HDDEDATA) DDE_FACK;
2024-03-19 22:24:30 +01:00
2024-03-19 22:38:33 +01:00
cancel:
bDbgAutoStateCtrl = TRUE; // enable automatic debugger state control
ResumeDebugger();
return hReturn;
2024-03-19 22:24:30 +01:00
case XTYP_REQUEST:
// quit on models without stack or illegal data format or not in running state
if (!bStackEnable || iFmt != uCF_HpObj || nState != SM_RUN)
2024-03-19 22:24:30 +01:00
return NULL;
// get item name
DdeQueryString(idDdeInst,hsz2,szBuffer,ARRAYSIZEOF(szBuffer),0);
nStkLvl = _tcstoul(szBuffer,&psz,10);
if (*psz != 0 || nStkLvl < 1) // invalid number format
return NULL;
2024-03-19 22:25:45 +01:00
if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state
2024-03-19 22:24:30 +01:00
return NULL;
while (nState!=nNextState) Sleep(0);
2024-03-19 22:37:03 +01:00
_ASSERT(nState==SM_SLEEP);
2024-03-19 22:24:30 +01:00
dwAddress = RPL_Pick(nStkLvl); // pick address of stack level "item" object
2024-03-19 22:24:30 +01:00
if (dwAddress == 0)
{
2024-03-19 22:37:03 +01:00
SwitchToState(SM_RUN); // run state
2024-03-19 22:24:30 +01:00
return NULL;
}
dwLoop = dwSize = (RPL_SkipOb(dwAddress) - dwAddress + 1) / 2;
2024-03-19 22:25:45 +01:00
lpHeader = (Chipset.type != 'X') ? BINARYHEADER48 : BINARYHEADER49;
2024-03-19 22:24:30 +01:00
// length of binary header
dwIndex = (DWORD) strlen(lpHeader);
2024-03-19 22:24:30 +01:00
// size of objectsize + header + object
dwSize += dwIndex + sizeof(DWORD);
// reserve memory
2024-03-19 22:38:33 +01:00
if ((lpData = HeapAlloc(hHeap,0,dwSize)) == NULL)
2024-03-19 22:24:30 +01:00
{
2024-03-19 22:37:03 +01:00
SwitchToState(SM_RUN); // run state
2024-03-19 22:24:30 +01:00
return NULL;
}
// save data length
*(DWORD *)lpData = dwLoop + dwIndex;
// copy header
2024-03-19 22:25:45 +01:00
memcpy(lpData + sizeof(DWORD),lpHeader,dwIndex);
2024-03-19 22:24:30 +01:00
// copy data
for (dwIndex += sizeof(DWORD);dwLoop--;++dwIndex,dwAddress += 2)
lpData[dwIndex] = Read2(dwAddress);
// write data
hReturn = DdeCreateDataHandle(idDdeInst,lpData,dwSize,0,hsz2,iFmt,0);
2024-03-19 22:38:33 +01:00
HeapFree(hHeap,0,lpData);
2024-03-19 22:24:30 +01:00
2024-03-19 22:37:03 +01:00
SwitchToState(SM_RUN); // run state
2024-03-19 22:24:30 +01:00
while (nState!=nNextState) Sleep(0);
2024-03-19 22:37:03 +01:00
_ASSERT(nState==SM_RUN);
2024-03-19 22:24:30 +01:00
return hReturn;
}
return NULL;
2024-03-19 22:37:03 +01:00
UNREFERENCED_PARAMETER(hConv);
UNREFERENCED_PARAMETER(dwData1);
UNREFERENCED_PARAMETER(dwData2);
2024-03-19 22:24:30 +01:00
}