1
0
Fork 0

Add Beta1 patch: "Add functions needed by netbios.exe, Fix some trouble with armada in protected mode" by h-a-l-9000.

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2711
This commit is contained in:
Peter Veenstra 2006-10-27 12:00:29 +00:00
parent 63fd72d956
commit 3653a5a3d5
5 changed files with 250 additions and 176 deletions

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: ipx.h,v 1.9 2006-02-26 13:46:31 qbix79 Exp $ */
/* $Id: ipx.h,v 1.10 2006-10-27 12:00:25 qbix79 Exp $ */
#ifndef DOSBOX_IPX_H
#define DOSBOX_IPX_H
@ -24,6 +24,12 @@
// Uncomment this for a lot of debug messages:
//#define IPX_DEBUGMSG
#ifdef IPX_DEBUGMSG
#define LOG_IPX LOG_MSG
#else
#define LOG_IPX(...)
#endif
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
@ -70,7 +76,7 @@ struct PackedIP {
struct nodeType {
Uint8 node[6];
}GCC_ATTRIBUTE(packed) ;
} GCC_ATTRIBUTE(packed) ;
struct IPXHeader {
Uint8 checkSum[2];
@ -100,13 +106,18 @@ class ECBClass {
public:
RealPt ECBAddr;
bool isInESRList;
ECBClass *prevECB;
ECBClass *prevECB; // Linked List
ECBClass *nextECB;
Bit8u iuflag;
Bit8u iuflag; // Need to save data since we are not always in
Bit16u mysocket; // real mode
#ifdef IPX_DEBUGMSG
Bit8u* databuffer; // received data is stored here until we get called
Bitu buflen; // by Interrupt
#ifdef IPX_DEBUGMSG
Bitu SerialNumber;
#endif
#endif
ECBClass(Bit16u segment, Bit16u offset);
Bit16u getSocket(void);
@ -119,6 +130,9 @@ public:
Bit16u getFragCount(void);
bool writeData();
void writeDataBuffer(Bit8u* buffer, Bit16u length);
void getFragDesc(Bit16u descNum, fragmentDescriptor *fragDesc);
RealPt getESRAddr(void);

View file

@ -57,6 +57,7 @@ bool PIC_RunQueue(void);
//Delay in milliseconds
void PIC_AddEvent(PIC_EventHandler handler,float delay,Bitu val=0);
void PIC_RemoveEvents(PIC_EventHandler handler);
void PIC_RemoveSpecificEvents(PIC_EventHandler handler, Bitu val);
void PIC_SetIRQMask(Bitu irq, bool masked);
#endif

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: ipx.cpp,v 1.10 2006-02-26 13:46:31 qbix79 Exp $ */
/* $Id: ipx.cpp,v 1.11 2006-10-27 12:00:29 qbix79 Exp $ */
#include "dosbox.h"
@ -49,14 +49,13 @@ struct ipxnetaddr {
Uint8 netnode[6];
} localIpxAddr;
Bit32u tcpPort;
Bit32u udpPort;
bool isIpxServer;
bool isIpxConnected;
IPaddress ipxClientIp; // IPAddress for client connection to server
IPaddress ipxServConnIp; // IPAddress for client connection to server
IPaddress ipxServConnIp; // IPAddress for client connection to server
UDPsocket ipxClientSocket;
int UDPChannel; // Channel used by UDP connection
Bit8u recvBuffer[IPXBUFFERSIZE]; // Incoming packet buffer
int UDPChannel; // Channel used by UDP connection
Bit8u recvBuffer[IPXBUFFERSIZE]; // Incoming packet buffer
static RealPt ipx_callback;
@ -92,13 +91,14 @@ Bitu ECBAmount = 0;
ECBClass::ECBClass(Bit16u segment, Bit16u offset) {
ECBAddr = RealMake(segment, offset);
databuffer = 0;
#ifdef IPX_DEBUGMSG
SerialNumber = ECBSerialNumber;
ECBSerialNumber++;
ECBAmount++;
LOG_MSG("ECB: SN%7d created. Number of ECBs: %3d, ESR %4x:%4x, ECB %4x:%4x",
LOG_IPX("ECB: SN%7d created. Number of ECBs: %3d, ESR %4x:%4x, ECB %4x:%4x",
SerialNumber,ECBAmount,
real_readw(RealSeg(ECBAddr),
RealOff(ECBAddr)+6),
@ -121,6 +121,41 @@ ECBClass::ECBClass(Bit16u segment, Bit16u offset) {
useECB->nextECB = this;
this->prevECB = useECB;
}
iuflag = getInUseFlag();
mysocket = getSocket();
}
void ECBClass::writeDataBuffer(Bit8u* buffer, Bit16u length) {
if(databuffer!=0) delete [] databuffer;
databuffer = new Bit8u[length];
memcpy(databuffer,buffer,length);
buflen=length;
}
bool ECBClass::writeData() {
Bitu length=buflen;
Bit8u* buffer = databuffer;
fragmentDescriptor tmpFrag;
setInUseFlag(USEFLAG_AVAILABLE);
Bitu fragCount = getFragCount();
Bitu bufoffset = 0;
for(Bitu i = 0;i < fragCount;i++) {
getFragDesc(i,&tmpFrag);
for(Bitu t = 0;t < tmpFrag.size;t++) {
real_writeb(tmpFrag.segment, tmpFrag.offset + t, buffer[bufoffset]);
bufoffset++;
if(bufoffset >= length) {
setCompletionFlag(COMP_SUCCESS);
setImmAddress(&buffer[22]); // Write in source node
return true;
}
}
}
if(bufoffset < length) {
setCompletionFlag(COMP_MALFORMED);
return false;
}
return false;
}
Bit16u ECBClass::getSocket(void) {
@ -162,10 +197,8 @@ RealPt ECBClass::getESRAddr(void) {
void ECBClass::NotifyESR(void) {
Bit32u ESRval = real_readd(RealSeg(ECBAddr), RealOff(ECBAddr)+4);
if(ESRval) {
#ifdef IPX_DEBUGMSG
LOG_MSG("ECB: SN%7d to be notified.", SerialNumber);
#endif
if(ESRval || databuffer) { // databuffer: write data at realmode/v86 time
// LOG_IPX("ECB: SN%7d to be notified.", SerialNumber);
// take the ECB out of the current list
if(prevECB == NULL) { // was the first in the list
ECBList = nextECB;
@ -190,7 +223,6 @@ void ECBClass::NotifyESR(void) {
prevECB = useECB;
}
isInESRList = true;
//LOG_MSG("ECB put to notification list");
PIC_ActivateIRQ(11);
}
// this one does not want to be notified, delete it right away
@ -210,7 +242,7 @@ void ECBClass::getImmAddress(Bit8u* immAddr) {
ECBClass::~ECBClass() {
#ifdef IPX_DEBUGMSG
ECBAmount--;
LOG_MSG("ECB: SN%7d destroyed. Remaining ECBs: %3d", SerialNumber,ECBAmount);
LOG_IPX("ECB: SN%7d destroyed. Remaining ECBs: %3d", SerialNumber,ECBAmount);
#endif
if(isInESRList) {
@ -225,6 +257,7 @@ ECBClass::~ECBClass() {
if(nextECB != NULL) nextECB->prevECB = prevECB;
}
}
if(databuffer!=0) delete [] databuffer;
}
@ -238,7 +271,6 @@ static bool sockInUse(Bit16u sockNum) {
static void OpenSocket(void) {
Bit16u sockNum, sockAlloc;
//LOG_MSG("IPX: DOSINT used.");
sockNum = swapByte(reg_dx);
if(socketCount >= SOCKTABLESIZE) {
@ -251,7 +283,8 @@ static void OpenSocket(void) {
sockAlloc = 0x4002;
while(sockInUse(sockAlloc) && (sockAlloc < 0x7fff)) sockAlloc++;
if(sockAlloc > 0x7fff) {
// I have no idea how this could happen if the IPX driver is limited to 150 open sockets at a time
// I have no idea how this could happen if the IPX driver
// is limited to 150 open sockets at a time
LOG_MSG("IPX: Out of dynamic sockets");
}
sockNum = sockAlloc;
@ -311,46 +344,59 @@ static bool IPX_Multiplex(void) {
return true;
}
static void IPX_AES_EventHandler(Bitu param)
{
ECBClass* tmpECB = ECBList;
ECBClass* tmp2ECB;
while(tmpECB!=0) {
tmp2ECB = tmpECB->nextECB;
if(tmpECB->iuflag==USEFLAG_AESCOUNT && param==(Bitu)tmpECB->ECBAddr) {
tmpECB->setCompletionFlag(COMP_SUCCESS);
tmpECB->setInUseFlag(USEFLAG_AVAILABLE);
tmpECB->NotifyESR();
// LOG_IPX("AES Notification: ECB S/N %d",tmpECB->SerialNumber);
return;
}
tmpECB = tmp2ECB;
}
LOG_MSG("!!!! Rouge AES !!!!" );
}
static void sendPacket(ECBClass* sendecb);
static void handleIpxRequest(void) {
ECBClass *tmpECB;
switch (reg_bx) {
case 0x0000: // Open socket
case 0x0000: // Open socket
OpenSocket();
#ifdef IPX_DEBUGMSG
LOG_MSG("IPX: Open socket %4x", swapByte(reg_dx));
#endif
LOG_IPX("IPX: Open socket %4x", swapByte(reg_dx));
break;
case 0x0001: // Close socket
#ifdef IPX_DEBUGMSG
LOG_MSG("IPX: Close socket %4x", swapByte(reg_dx));
#endif
case 0x0001: // Close socket
LOG_IPX("IPX: Close socket %4x", swapByte(reg_dx));
CloseSocket();
break;
case 0x0002: // get local target
// es:si
// Currently no support for multiple networks
// es:si
// Currently no support for multiple networks
for(Bitu i = 0; i < 6; i++)
real_writeb(SegValue(es),reg_di+i,real_readb(SegValue(es),reg_si+i+4));
reg_cx=1; // time ticks expected
reg_al=0x00;//success
reg_cx=1; // time ticks expected
reg_al=0x00; //success
break;
case 0x0003: // Send packet
case 0x0003: // Send packet
tmpECB = new ECBClass(SegValue(es),reg_si);
if(!incomingPacket.connected) {
tmpECB = new ECBClass(SegValue(es),reg_si);
tmpECB->setInUseFlag(USEFLAG_AVAILABLE);
tmpECB->setCompletionFlag(COMP_UNDELIVERABLE);
delete tmpECB; // not notify?
reg_al = 0xff; // Failure
} else {
tmpECB = new ECBClass(SegValue(es),reg_si);
tmpECB->setInUseFlag(USEFLAG_SENDING);
//LOG_MSG("IPX: Sending packet on %4x", tmpECB->getSocket());
//LOG_IPX("IPX: Sending packet on %4x", tmpECB->getSocket());
reg_al = 0x00; // Success
sendPacket(tmpECB);
}
@ -358,6 +404,7 @@ static void handleIpxRequest(void) {
break;
case 0x0004: // Listen for packet
tmpECB = new ECBClass(SegValue(es),reg_si);
// LOG_IPX("ECB: SN%7d RECEIVE.", tmpECB->SerialNumber);
if(!sockInUse(tmpECB->getSocket())) { // Socket is not open
reg_al = 0xff;
tmpECB->setInUseFlag(USEFLAG_AVAILABLE);
@ -366,73 +413,86 @@ static void handleIpxRequest(void) {
} else {
reg_al = 0x00; // Success
tmpECB->setInUseFlag(USEFLAG_LISTENING);
/*LOG_MSG("IPX: Listen for packet on 0x%4x - ESR address %4x:%4x",
/*LOG_IPX("IPX: Listen for packet on 0x%4x - ESR address %4x:%4x",
tmpECB->getSocket(),
RealSeg(tmpECB->getESRAddr()),
RealOff(tmpECB->getESRAddr()));*/
}
break;
case 0x0006: // cancel operation
{
RealPt ecbaddress = RealMake(SegValue(es),reg_si);
ECBClass* tmpECB= ECBList;
ECBClass* tmp2ECB;
while(tmpECB) {
tmp2ECB=tmpECB->nextECB;
if(tmpECB->ECBAddr == ecbaddress) {
tmpECB->setInUseFlag(USEFLAG_AVAILABLE);
tmpECB->setCompletionFlag(COMP_CANCELLED);
delete tmpECB;
reg_al=0; // Success
#ifdef IPX_DEBUGMSG
LOG_MSG("IPX: ECB canceled.");
#endif
return;
}
tmpECB=tmp2ECB;
}
reg_al=0xff; // Fail
break;
}
case 0x0008: // Get interval marker
// ????
break;
case 0x0009: // Get internetwork address
{
#ifdef IPX_DEBUGMSG
LOG_MSG("IPX: Get internetwork address %2x:%2x:%2x:%2x:%2x:%2x", localIpxAddr.netnode[5], localIpxAddr.netnode[4], localIpxAddr.netnode[3], localIpxAddr.netnode[2], localIpxAddr.netnode[1], localIpxAddr.netnode[0]);
#endif
Bit8u * addrptr = (Bit8u *)&localIpxAddr;
for(Bit16u i=0;i<10;i++) {
real_writeb(SegValue(es),reg_si+i,addrptr[i]);
}
break;
}
case 0x000a: // Relinquish control
// Idle thingy
break;
case 0x000b: // Disconnect from Target
// We don't even connect
break;
case 0x0010: // SPX install check
{
reg_al=0; // SPX not installed
break;
}
case 0x001a: // get driver maximum packet size
{
reg_cx=0; // retry count
reg_ax=IPXBUFFERSIZE; // max packet size
break;
case 0x0005: // SCHEDULE IPX EVENT
case 0x0007: // SCHEDULE SPECIAL IPX EVENT
{
tmpECB = new ECBClass(SegValue(es),reg_si);
// LOG_IPX("ECB: SN%7d AES. T=%fms.", tmpECB->SerialNumber,
// (1000.0f/(1193182.0f/65536.0f))*(float)reg_ax);
PIC_AddEvent(IPX_AES_EventHandler,
(1000.0f/(1193182.0f/65536.0f))*(float)reg_ax,(Bitu)tmpECB->ECBAddr);
tmpECB->setInUseFlag(USEFLAG_AESCOUNT);
break;
}
case 0x0006: // cancel operation
{
RealPt ecbaddress = RealMake(SegValue(es),reg_si);
ECBClass* tmpECB= ECBList;
ECBClass* tmp2ECB;
while(tmpECB) {
tmp2ECB=tmpECB->nextECB;
if(tmpECB->ECBAddr == ecbaddress) {
if(tmpECB->getInUseFlag()==USEFLAG_AESCOUNT)
PIC_RemoveSpecificEvents(IPX_AES_EventHandler,(Bitu)ecbaddress);
tmpECB->setInUseFlag(USEFLAG_AVAILABLE);
tmpECB->setCompletionFlag(COMP_CANCELLED);
delete tmpECB;
reg_al=0; // Success
LOG_IPX("IPX: ECB canceled.");
return;
}
tmpECB=tmp2ECB;
}
reg_al=0xff; // Fail
break;
}
case 0x0008: // Get interval marker
reg_ax = mem_readw(0x46c); // BIOS_TIMER
break;
case 0x0009: // Get internetwork address
{
LOG_IPX("IPX: Get internetwork address %2x:%2x:%2x:%2x:%2x:%2x",
localIpxAddr.netnode[5], localIpxAddr.netnode[4],
localIpxAddr.netnode[3], localIpxAddr.netnode[2],
localIpxAddr.netnode[1], localIpxAddr.netnode[0]);
Bit8u * addrptr = (Bit8u *)&localIpxAddr;
for(Bit16u i=0;i<10;i++)
real_writeb(SegValue(es),reg_si+i,addrptr[i]);
break;
}
case 0x000a: // Relinquish control
break; // Idle thingy
case 0x000b: // Disconnect from Target
break; // We don't even connect
case 0x000d: // get packet size
reg_cx=0; // retry count
reg_ax=1024; // real implementation returns 1024
break;
case 0x0010: // SPX install check
reg_al=0; // SPX not installed
break;
case 0x001a: // get driver maximum packet size
reg_cx=0; // retry count
reg_ax=IPXBUFFERSIZE; // max packet size: something near the
// ethernet packet size
break;
default:
LOG_MSG("Unhandled IPX function: %4x", reg_bx);
break;
}
}
// Entrypoint handler
@ -506,19 +566,16 @@ static void pingSend(void) {
static void receivePacket(Bit8u *buffer, Bit16s bufSize) {
ECBClass *useECB;
ECBClass *nextECB;
fragmentDescriptor tmpFrag;
Bit16u i, fragCount,t;
Bit16s bufoffset;
Bit16u *bufword = (Bit16u *)buffer;
Bit16u useSocket = swapByte(bufword[8]);
Bit32u hostaddr;
IPXHeader * tmpHeader;
tmpHeader = (IPXHeader *)buffer;
// Check to see if ping packet
if(useSocket == 0x2) {
// Is this a broadcast?
if((tmpHeader->dest.addr.byIP.host == 0xffffffff) && (tmpHeader->dest.addr.byIP.port == 0xffff)) {
if((tmpHeader->dest.addr.byIP.host == 0xffffffff) &&
(tmpHeader->dest.addr.byIP.port == 0xffff)) {
// Yes. We should return the ping back to the sender
IPaddress tmpAddr;
UnpackIP(tmpHeader->src.addr.byIP, &tmpAddr);
@ -531,40 +588,14 @@ static void receivePacket(Bit8u *buffer, Bit16s bufSize) {
while(useECB != NULL)
{
nextECB = useECB->nextECB;
if(useECB->getInUseFlag() == USEFLAG_LISTENING) {
if(useECB->getSocket() == useSocket) {
useECB->setInUseFlag(USEFLAG_AVAILABLE);
fragCount = useECB->getFragCount();
bufoffset = 0;
for(i=0;i<fragCount;i++) {
useECB->getFragDesc(i,&tmpFrag);
for(t=0;t<tmpFrag.size;t++) {
real_writeb(tmpFrag.segment, tmpFrag.offset+t, buffer[bufoffset]);
bufoffset++;
if(bufoffset>=bufSize) {
useECB->setCompletionFlag(COMP_SUCCESS);
useECB->setImmAddress(&buffer[22]); // Write in source node
hostaddr = *((Bit32u *)&buffer[24]);
#ifdef IPX_DEBUGMSG
LOG_MSG("IPX: Received packet of %d bytes from %d.%d.%d.%d (%x CRC)", bufSize, CONVIP(hostaddr), packetCRC(&buffer[30], bufSize-30));
#endif
useECB->NotifyESR();
return;
}
}
}
if(bufoffset < bufSize) {
useECB->setCompletionFlag(COMP_MALFORMED);
useECB->NotifyESR();
return;
}
}
if(useECB->iuflag == USEFLAG_LISTENING && useECB->mysocket == useSocket) {
useECB->writeDataBuffer(buffer, bufSize);
useECB->NotifyESR();
return;
}
useECB = nextECB;
}
#ifdef IPX_DEBUGMSG
LOG_MSG("IPX: RX Packet loss!");
#endif
LOG_IPX("IPX: RX Packet loss!");
}
static void IPX_ClientLoop(void) {
@ -608,15 +639,23 @@ static void sendPacket(ECBClass* sendecb) {
// Must put source address into header
Bit8u * addrptr;
// source netnum
addrptr = (Bit8u *)&localIpxAddr.netnum;
for(Bit16u m=0;m<4;m++) {
real_writeb(tmpFrag.segment,tmpFrag.offset+m+18,addrptr[m]);
}
// source node number
addrptr = (Bit8u *)&localIpxAddr.netnode;
for(Bit16u m=0;m<6;m++) {
real_writeb(tmpFrag.segment,tmpFrag.offset+m+22,addrptr[m]);
}
// Source socket
real_writew(tmpFrag.segment,tmpFrag.offset+28, swapByte(sendecb->getSocket()));
// blank checksum
real_writew(tmpFrag.segment,tmpFrag.offset, 0xffff);
}
for(t=0;t<tmpFrag.size;t++) {
outbuffer[packetsize] = real_readb(tmpFrag.segment, tmpFrag.offset + t);
packetsize++;
@ -632,11 +671,15 @@ static void sendPacket(ECBClass* sendecb) {
// Add length and source socket to IPX header
wordptr = (Bit16u *)&outbuffer[0];
// Blank CRC
wordptr[0] = 0xffff;
//wordptr[0] = 0xffff;
// Length
wordptr[1] = swapByte(packetsize);
// Source socket
wordptr[14] = swapByte(sendecb->getSocket());
//wordptr[14] = swapByte(sendecb->getSocket());
sendecb->getFragDesc(0,&tmpFrag);
real_writew(tmpFrag.segment,tmpFrag.offset+2, swapByte(packetsize));
Bit8u immedAddr[6];
sendecb->getImmAddress(immedAddr);
@ -657,7 +700,7 @@ static void sendPacket(ECBClass* sendecb) {
if(addrptr[m]!=outbuffer[m+0xa])isloopback=false;
if(immedAddr[m]!=0xff) islocalbroadcast=false;
}
LOG_IPX("SEND crc:%2x",packetCRC(&outbuffer[0], packetsize));
if(!isloopback) {
outPacket.channel = UDPChannel;
outPacket.data = (Uint8 *)&outbuffer[0];
@ -674,16 +717,15 @@ static void sendPacket(ECBClass* sendecb) {
return;
} else {
sendecb->setCompletionFlag(COMP_SUCCESS);
#ifdef IPX_DEBUGMSG
LOG_MSG("Packet sent: size: %d",packetsize);
#endif
LOG_IPX("Packet sent: size: %d",packetsize);
}
}
else sendecb->setCompletionFlag(COMP_SUCCESS);
if(isloopback||islocalbroadcast) {
// Send packet back to ourselves.
receivePacket(&outbuffer[0],packetsize);
#ifdef IPX_DEBUGMSG
LOG_MSG("Packet back: loopback:%d, broadcast:%d",isloopback,isbroadcast);
#endif
LOG_IPX("Packet back: loopback:%d, broadcast:%d",isloopback,islocalbroadcast);
}
sendecb->NotifyESR();
}
@ -710,14 +752,13 @@ bool ConnectToServer(char *strAddr) {
int numsent;
UDPpacket regPacket;
IPXHeader regHeader;
if(!SDLNet_ResolveHost(&ipxServConnIp, strAddr, (Bit16u)udpPort)) {
if(!SDLNet_ResolveHost(&ipxServConnIp, strAddr, (Bit16u)tcpPort)) {
// Generate the MAC address. This is made by zeroing out the first two
// octets and then using the actual IP address for the last 4 octets.
// This idea is from the IPX over IP implementation as specified in RFC 1234:
// http://www.faqs.org/rfcs/rfc1234.html
// Select an anonymous UDP port
ipxClientSocket = SDLNet_UDP_Open(0);
if(ipxClientSocket) {
@ -743,7 +784,8 @@ bool ConnectToServer(char *strAddr) {
regPacket.len = sizeof(regHeader);
regPacket.maxlen = sizeof(regHeader);
regPacket.channel = UDPChannel;
// Send registration string to server. If server doesn't get this, client will not be registered
// Send registration string to server. If server doesn't get
// this, client will not be registered
numsent = SDLNet_UDP_Send(ipxClientSocket, regPacket.channel, &regPacket);
if(!numsent) {
@ -751,7 +793,8 @@ bool ConnectToServer(char *strAddr) {
SDLNet_UDP_Close(ipxClientSocket);
return false;
} else {
// Wait for return packet from server. This will contain our IPX address and port num
// Wait for return packet from server.
// This will contain our IPX address and port num
Bits result;
Bit32u ticks, elapsed;
ticks = GetTicks();
@ -898,11 +941,11 @@ public:
}
bool startsuccess;
if(!cmd->FindCommand(2, temp_line)) {
tcpPort = 213;
udpPort = 213;
} else {
tcpPort = strtol(temp_line.c_str(), NULL, 10);
udpPort = strtol(temp_line.c_str(), NULL, 10);
}
startsuccess = IPX_StartServer((Bit16u)tcpPort);
startsuccess = IPX_StartServer((Bit16u)udpPort);
if(startsuccess) {
WriteOut("IPX Tunneling Server started\n");
isIpxServer = true;
@ -923,7 +966,6 @@ public:
DisconnectFromServer(false);
IPX_StopServer();
WriteOut("IPX Tunneling Server stopped.");
// Don't know how to stop the timer just yet.
}
return;
}
@ -940,9 +982,9 @@ public:
strcpy(strHost, temp_line.c_str());
if(!cmd->FindCommand(3, temp_line)) {
tcpPort = 213;
udpPort = 213;
} else {
tcpPort = strtol(temp_line.c_str(), NULL, 10);
udpPort = strtol(temp_line.c_str(), NULL, 10);
}
if(ConnectToServer(strHost)) {
@ -959,7 +1001,6 @@ public:
return;
}
// TODO: Send a packet to the server notifying of disconnect
WriteOut("IPX Tunneling Client disconnected from server.\n");
DisconnectFromServer(false);
return;
@ -971,7 +1012,7 @@ public:
if(isIpxServer) WriteOut("ACTIVE\n"); else WriteOut("INACTIVE\n");
WriteOut("Client status: ");
if(incomingPacket.connected) {
WriteOut("CONNECTED -- Server at %d.%d.%d.%d port %d\n", CONVIP(ipxServConnIp.host), tcpPort);
WriteOut("CONNECTED -- Server at %d.%d.%d.%d port %d\n", CONVIP(ipxServConnIp.host), udpPort);
} else {
WriteOut("DISCONNECTED\n");
}
@ -1017,30 +1058,25 @@ static void IPXNET_ProgramStart(Program * * make) {
*make=new IPXNET;
}
Bitu IPX_ESRHandler1(void) {
#ifdef IPX_DEBUGMSG
LOG_MSG("ESRhandler entered" );
#endif
Bitu IPX_ESRHandler(void) {
LOG_IPX("ESR: >>>>>>>>>>>>>>>" );
while(ESRList!=NULL) {
#ifdef IPX_DEBUGMSG
LOG_MSG("ECB: SN%7d notified.", ESRList->SerialNumber);
#endif
// setup registers
SegSet16(es, RealSeg(ESRList->ECBAddr));
reg_si = RealOff(ESRList->ECBAddr);
reg_al = 0xff;
CALLBACK_RunRealFar(RealSeg(ESRList->getESRAddr()), RealOff(ESRList->getESRAddr()));
// LOG_IPX("ECB: SN%7d notified.", ESRList->SerialNumber);
if(ESRList->databuffer) ESRList->writeData();
if(ESRList->getESRAddr()) {
// setup registers
SegSet16(es, RealSeg(ESRList->ECBAddr));
reg_si = RealOff(ESRList->ECBAddr);
reg_al = 0xff;
CALLBACK_RunRealFar(RealSeg(ESRList->getESRAddr()),
RealOff(ESRList->getESRAddr()));
}
delete ESRList;
} // while
IO_WriteB(0xa0,0x63); //EOI11
IO_WriteB(0x20,0x62); //EOI2
#ifdef IPX_DEBUGMSG
LOG_MSG("ESR loop done.");
#endif
LOG_IPX("ESR: <<<<<<<<<<<<<<<");
return CBRET_NONE;
}
@ -1079,17 +1115,15 @@ public:
callback_ipxint.Install(&IPX_IntHandler,CB_IRET,"IPX (int 7a)");
callback_ipxint.Set_RealVec(0x7a);
callback_esr.Allocate(&IPX_ESRHandler1,"IPX_ESR");
callback_esr.Allocate(&IPX_ESRHandler,"IPX_ESR");
Bit16u call_ipxesr1 = callback_esr.Get_callback();
if(!dospage) dospage = DOS_GetMemory(2); // can not be freed yet
PhysPt phyDospage = PhysMake(dospage,0);
#ifdef IPX_DEBUGMSG
LOG_MSG("IPX INT address: %x", ipx_intcallback);
LOG_MSG("ESR callback address: %x, HandlerID %d", phyDospage,call_ipxesr1);
#endif
LOG_IPX("ESR callback address: %x, HandlerID %d", phyDospage,call_ipxesr1);
//save registers
phys_writeb(phyDospage+0,(Bit8u)0xFA); // CLI
phys_writeb(phyDospage+1,(Bit8u)0x60); // PUSHA
@ -1127,6 +1161,7 @@ public:
~IPX() {
Section_prop * section = static_cast<Section_prop *>(m_configuration);
PIC_RemoveEvents(IPX_AES_EventHandler);
if(!section->Get_bool("ipx")) return;
if(isIpxServer) {

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: ipxserver.cpp,v 1.7 2006-02-09 11:47:49 qbix79 Exp $ */
/* $Id: ipxserver.cpp,v 1.8 2006-10-27 12:00:29 qbix79 Exp $ */
#include "dosbox.h"
@ -135,7 +135,7 @@ static void ackClient(IPaddress clientAddr) {
PackIP(clientAddr, &regHeader.dest.addr.byIP);
SDLNet_Write16(0x2, regHeader.dest.socket);
SDLNet_Write32(0, regHeader.src.network);
SDLNet_Write32(1, regHeader.src.network);
PackIP(ipxServerIp, &regHeader.src.addr.byIP);
SDLNet_Write16(0x2, regHeader.src.socket);
regHeader.transControl = 0;

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: pic.cpp,v 1.35 2006-05-23 10:30:02 qbix79 Exp $ */
/* $Id: pic.cpp,v 1.36 2006-10-27 12:00:29 qbix79 Exp $ */
#include <list>
@ -393,6 +393,30 @@ void PIC_AddEvent(PIC_EventHandler handler,float delay,Bitu val) {
AddEntry(entry);
}
void PIC_RemoveSpecificEvents(PIC_EventHandler handler, Bitu val) {
PICEntry * entry=pic.next_entry;
PICEntry * prev_entry;
prev_entry = 0;
while (entry) {
if ((entry->event == handler) && (entry->value == val)) {
if (prev_entry) {
prev_entry->next=entry->next;
entry->next=pic.free_entry;
pic.free_entry=entry;
entry=prev_entry->next;
continue;
} else {
pic.next_entry=entry->next;
entry->next=pic.free_entry;
pic.free_entry=entry;
entry=pic.next_entry;
continue;
}
}
prev_entry=entry;
entry=entry->next;
}
}
void PIC_RemoveEvents(PIC_EventHandler handler) {
PICEntry * entry=pic.next_entry;