From 2428a803213a6d7f430d9f440ba80bedd52bb522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Fri, 26 Aug 2005 19:16:20 +0000 Subject: [PATCH] ipx-update (h-a-l-9000) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2291 --- src/hardware/ipx.cpp | 456 ++++++++++++++++--------------------------- 1 file changed, 167 insertions(+), 289 deletions(-) diff --git a/src/hardware/ipx.cpp b/src/hardware/ipx.cpp index ed6bb2e6..33c3bafb 100644 --- a/src/hardware/ipx.cpp +++ b/src/hardware/ipx.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ipx.cpp,v 1.7 2005-07-30 10:02:39 qbix79 Exp $ */ +/* $Id: ipx.cpp,v 1.8 2005-08-26 19:16:20 c2woody Exp $ */ #include "dosbox.h" @@ -28,7 +28,6 @@ #include "cross.h" #include "support.h" #include "cpu.h" -#include "SDL_net.h" #include "regs.h" #include "inout.h" #include "setup.h" @@ -45,20 +44,16 @@ #define SOCKTABLESIZE 150 // DOS IPX driver was limited to 150 open sockets - struct ipxnetaddr { Uint8 netnum[4]; // Both are big endian Uint8 netnode[6]; } localIpxAddr; - - Bit32u tcpPort; bool isIpxServer; bool isIpxConnected; IPaddress ipxClientIp; // IPAddress for client connection to server IPaddress ipxServConnIp; // IPAddress for client connection to server -//TCPsocket ipxTCPClientSocket; UDPsocket ipxClientSocket; int UDPChannel; // Channel used by UDP connection Bit8u recvBuffer[IPXBUFFERSIZE]; // Incoming packet buffer @@ -67,10 +62,11 @@ static RealPt ipx_callback; SDLNet_SocketSet clientSocketSet; -static bool ESRnotificationRequired = false; - packetBuffer incomingPacket; +static Bit16u socketCount; +static Bit16u opensockets[SOCKTABLESIZE]; + static Bit16u swapByte(Bit16u sockNum) { return (((sockNum>> 8)) | (sockNum << 8)); } @@ -166,7 +162,6 @@ 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); @@ -227,8 +222,7 @@ ECBClass::~ECBClass() { } } -static Bit16u socketCount; -static Bit16u opensockets[SOCKTABLESIZE]; + static bool sockInUse(Bit16u sockNum) { for(Bitu i=0;inextECB; if(tmpECB->getSocket()==sockNum) { tmpECB->setCompletionFlag(COMP_CANCELLED); + tmpECB->setInUseFlag(USEFLAG_AVAILABLE); delete tmpECB; } tmpECB = tmp2ECB; @@ -311,7 +306,6 @@ static bool IPX_Multiplex(void) { return true; } -//static void sendPackets(); static void sendPacket(ECBClass* sendecb); static void handleIpxRequest(void) { @@ -320,10 +314,14 @@ static void handleIpxRequest(void) { switch (reg_bx) { case 0x0000: // Open socket OpenSocket(); +#ifdef IPX_DEBUGMSG LOG_MSG("IPX: Open socket %4x", swapByte(reg_dx)); +#endif break; case 0x0001: // Close socket +#ifdef IPX_DEBUGMSG LOG_MSG("IPX: Close socket %4x", swapByte(reg_dx)); +#endif CloseSocket(); break; case 0x0002: // get local target @@ -332,26 +330,24 @@ static void handleIpxRequest(void) { case 0x0003: // Send packet if(!incomingPacket.connected) { - tmpECB = new ECBClass(SegValue(es),reg_si);//CreateECB(RealMake(SegValue(es), reg_si),true); + tmpECB = new ECBClass(SegValue(es),reg_si); tmpECB->setInUseFlag(USEFLAG_AVAILABLE); tmpECB->setCompletionFlag(COMP_UNDELIVERABLE); delete tmpECB; // not notify? - //DeleteECB(tmpECB); reg_al = 0xff; // Failure } else { - tmpECB = new ECBClass(SegValue(es),reg_si);//CreateECB(RealMake(SegValue(es), reg_si),true); + tmpECB = new ECBClass(SegValue(es),reg_si); tmpECB->setInUseFlag(USEFLAG_SENDING); //LOG_MSG("IPX: Sending packet on %4x", tmpECB->getSocket()); reg_al = 0x00; // Success sendPacket(tmpECB); } - - //sendPackets(); + break; case 0x0004: // Listen for packet - tmpECB = new ECBClass(SegValue(es),reg_si);//CreateECB(RealMake(SegValue(es), reg_si),false); - if(!sockInUse(tmpECB->getSocket())) { - reg_al = 0xff; // Socket is not open + tmpECB = new ECBClass(SegValue(es),reg_si); + if(!sockInUse(tmpECB->getSocket())) { // Socket is not open + reg_al = 0xff; tmpECB->setInUseFlag(USEFLAG_AVAILABLE); tmpECB->setCompletionFlag(COMP_HARDWAREERROR); delete tmpECB; @@ -374,14 +370,18 @@ static void handleIpxRequest(void) { while(tmpECB) { tmp2ECB=tmpECB->nextECB; if(tmpECB->ECBAddr == ecbaddress) { - delete tmpECB; // TODO: invoke flags... check if it can be canceled + 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=0; // Success + reg_al=0xff; // Fail break; } case 0x0008: // Get interval marker @@ -389,12 +389,11 @@ static void handleIpxRequest(void) { 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]); - Bit8u * addrptr; - Bits i; - - addrptr = (Bit8u *)&localIpxAddr; - for(i=0;i<10;i++) { +#endif + Bit8u * addrptr = (Bit8u *)&localIpxAddr; + for(Bit16u i=0;i<10;i++) { real_writeb(SegValue(es),reg_si+i,addrptr[i]); } break; @@ -426,12 +425,6 @@ Bitu IPX_IntHandler(void) { return CBRET_NONE; } -static void disconnectServer(bool unexpected) { - // There is no Timer remove code, hence this has to be done manually - incomingPacket.connected = false; - if(unexpected) LOG_MSG("IPX: Server disconnected unexpectedly"); -} - static void pingAck(IPaddress retAddr) { IPXHeader regHeader; UDPpacket regPacket; @@ -503,7 +496,7 @@ static void receivePacket(Bit8u *buffer, Bit16s bufSize) { // 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); @@ -530,13 +523,10 @@ static void receivePacket(Bit8u *buffer, Bit16s 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 - +#endif useECB->NotifyESR(); - //DeleteECB(useECB); return; } } @@ -544,7 +534,6 @@ static void receivePacket(Bit8u *buffer, Bit16s bufSize) { if(bufoffset < bufSize) { useECB->setCompletionFlag(COMP_MALFORMED); useECB->NotifyESR(); - //DeleteECB(useECB); return; } } @@ -556,7 +545,7 @@ static void receivePacket(Bit8u *buffer, Bit16s bufSize) { #endif } -static void IPX_UDPClientLoop(void) { +static void IPX_ClientLoop(void) { int numrecv; UDPpacket inPacket; inPacket.data = (Uint8 *)recvBuffer; @@ -570,190 +559,127 @@ static void IPX_UDPClientLoop(void) { if(numrecv) receivePacket(inPacket.data, inPacket.len); //}while(numrecv>0); - } -// don't waste time scanning the list -static void sendPacket(ECBClass* sendecb) { - char outbuffer[IPXBUFFERSIZE]; - fragmentDescriptor tmpFrag; - Bit16u i, fragCount,t; - Bit16s packetsize; - Bit16u *wordptr; - Bits result; - UDPpacket outPacket; - - //if(useECB->getInUseFlag() == USEFLAG_SENDING) - // { - sendecb->setInUseFlag(USEFLAG_AVAILABLE); - packetsize = 0; - fragCount = sendecb->getFragCount(); - for(i=0;igetFragDesc(i,&tmpFrag); - if(i==0) { - // Fragment containing IPX header - // Must put source address into header - Bit8u * addrptr; - Bits m; - addrptr = (Bit8u *)&localIpxAddr.netnode; - for(m=0;m<6;m++) { - real_writeb(tmpFrag.segment,tmpFrag.offset+m+22,addrptr[m]); - } - } - for(t=0;t=IPXBUFFERSIZE) { - LOG_MSG("IPX: Packet size to be sent greater than %d bytes.", IPXBUFFERSIZE); - sendecb->setCompletionFlag(COMP_UNDELIVERABLE); - sendecb->NotifyESR(); - //DeleteECB(useECB); - return; - } - } - } - - // Add length and source socket to IPX header - wordptr = (Bit16u *)&outbuffer[0]; - // Blank CRC - wordptr[0] = 0xffff; - // Length - wordptr[1] = swapByte(packetsize); - // Source socket - wordptr[14] = swapByte(sendecb->getSocket()); - outPacket.channel = UDPChannel; - outPacket.data = (Uint8 *)&outbuffer[0]; - outPacket.len = packetsize; - outPacket.maxlen = packetsize; - // Since we're using a channel, we won't send the IP address again - result = SDLNet_UDP_Send(ipxClientSocket, UDPChannel, &outPacket); - if(result == 0) { - LOG_MSG("IPX: Could not send packet: %s", SDLNet_GetError()); - sendecb->setCompletionFlag(COMP_UNDELIVERABLE); - sendecb->NotifyESR(); - //DeleteECB(useECB); - disconnectServer(true); - //return; - } else { - sendecb->setInUseFlag(USEFLAG_AVAILABLE); - sendecb->setCompletionFlag(COMP_SUCCESS); -#ifdef IPX_DEBUGMSG - LOG_MSG("Packet sent: size: %d",packetsize); -#endif - sendecb->NotifyESR(); - } - //} -} -static void sendPackets() { - ECBClass *useECB; - ECBClass *nextECB; - char outbuffer[IPXBUFFERSIZE]; - fragmentDescriptor tmpFrag; - Bit16u i, fragCount,t; - Bit16s packetsize; - Bit16u *wordptr; - Bits result; - UDPpacket outPacket; - - useECB = ECBList; - while(useECB != NULL) { - nextECB = useECB->nextECB; - if(useECB->getInUseFlag() == USEFLAG_SENDING) { - useECB->setInUseFlag(USEFLAG_AVAILABLE); - packetsize = 0; - fragCount = useECB->getFragCount(); - for(i=0;igetFragDesc(i,&tmpFrag); - if(i==0) { - // Fragment containing IPX header - // Must put source address into header - Bit8u * addrptr; - Bits m; - - addrptr = (Bit8u *)&localIpxAddr.netnode; - for(m=0;m<6;m++) { - real_writeb(tmpFrag.segment,tmpFrag.offset+m+22,addrptr[m]); - } - } - for(t=0;t=IPXBUFFERSIZE) { - LOG_MSG("IPX: Packet size to be sent greater than %d bytes.", IPXBUFFERSIZE); - useECB->setCompletionFlag(COMP_UNDELIVERABLE); - useECB->NotifyESR(); - //DeleteECB(useECB); - goto nextECB; - } - } - } - - // Add length and source socket to IPX header - wordptr = (Bit16u *)&outbuffer[0]; - // Blank CRC - wordptr[0] = 0xffff; - // Length - wordptr[1] = swapByte(packetsize); - // Source socket - wordptr[14] = swapByte(useECB->getSocket()); - - outPacket.channel = UDPChannel; - outPacket.data = (Uint8 *)&outbuffer[0]; - outPacket.len = packetsize; - outPacket.maxlen = packetsize; - // Since we're using a channel, we won't send the IP address again - result = SDLNet_UDP_Send(ipxClientSocket, UDPChannel, &outPacket); - if(result == 0) { - LOG_MSG("IPX: Could not send packet: %s", SDLNet_GetError()); - useECB->setCompletionFlag(COMP_UNDELIVERABLE); - useECB->NotifyESR(); - //DeleteECB(useECB); - disconnectServer(true); - //return; - } else { - useECB->setInUseFlag(USEFLAG_AVAILABLE); - useECB->setCompletionFlag(COMP_SUCCESS); - //LOG_MSG("Packet sent: size: %d",packetsize); - useECB->NotifyESR(); - //DeleteECB(useECB); - } - } -nextECB: - useECB = nextECB; +void DisconnectFromServer(bool unexpected) { + if(unexpected) LOG_MSG("IPX: Server disconnected unexpectedly"); + if(incomingPacket.connected) { + incomingPacket.connected = false; + TIMER_DelTickHandler(&IPX_ClientLoop); + SDLNet_UDP_Close(ipxClientSocket); } } -//RealPt ESRJmpDisplacementAddr; -//RealPt ESRTargetAddr; -//RealPt ESRDummyRetAddr; -/* -void repeatESR(bool rep) -{ - if(rep) real_writeb( - RealSeg(ESRJmpDisplacementAddr), - RealOff(ESRJmpDisplacementAddr), - (Bit8u)0xF5); - else real_writeb( - RealSeg(ESRJmpDisplacementAddr), - RealOff(ESRJmpDisplacementAddr), - (Bit8u)0); -} -*/ -ECBClass* ESRHANDLER_useECB; -static void IPX_ClientLoop(void) { +static void sendPacket(ECBClass* sendecb) { + Bit8u outbuffer[IPXBUFFERSIZE]; + fragmentDescriptor tmpFrag; + Bit16u i, fragCount,t; + Bit16s packetsize; + Bit16u *wordptr; + Bits result; + UDPpacket outPacket; + + sendecb->setInUseFlag(USEFLAG_AVAILABLE); + packetsize = 0; + fragCount = sendecb->getFragCount(); + for(i=0;igetFragDesc(i,&tmpFrag); + if(i==0) { + // Fragment containing IPX header + // Must put source address into header + Bit8u * addrptr; + + addrptr = (Bit8u *)&localIpxAddr.netnum; + for(Bit16u m=0;m<4;m++) { + real_writeb(tmpFrag.segment,tmpFrag.offset+m+18,addrptr[m]); + } + addrptr = (Bit8u *)&localIpxAddr.netnode; + for(Bit16u m=0;m<6;m++) { + real_writeb(tmpFrag.segment,tmpFrag.offset+m+22,addrptr[m]); + } + } + for(t=0;t=IPXBUFFERSIZE) { + LOG_MSG("IPX: Packet size to be sent greater than %d bytes.", IPXBUFFERSIZE); + sendecb->setCompletionFlag(COMP_UNDELIVERABLE); + sendecb->NotifyESR(); + return; + } + } + } + + // Add length and source socket to IPX header + wordptr = (Bit16u *)&outbuffer[0]; + // Blank CRC + wordptr[0] = 0xffff; + // Length + wordptr[1] = swapByte(packetsize); + // Source socket + wordptr[14] = swapByte(sendecb->getSocket()); - IPX_UDPClientLoop(); - // Send outgoing packets - //sendPackets(); -} + // filter out broadcasts and local loopbacks + // ok, the situation is: + // Warcraft1 is allergic to having broadcast packets looped back. + // C&C1 is allergic to not having broadcast packets looped back. + // Warcraft1 broadcasts to 00 00 00 00 : FF FF FF FF FF FF + // C&C1 broadcasts to FF FF FF FF : FF FF FF FF FF FF + // Some other games don't care. + // I assume FF... does local loopback, 00... doesn't. + // Let's hope the bug isn't somewhere else.. + bool islocalbroadcast=true; + bool isloopback=true; + + Bit8u * addrptr; + + addrptr = (Bit8u *)&localIpxAddr.netnum; + for(Bitu m=0;m<4;m++) { + if(addrptr[m]!=outbuffer[m+0x6])isloopback=false; + if(outbuffer[m+0x6]!=0xff) islocalbroadcast=false; + } + addrptr = (Bit8u *)&localIpxAddr.netnode; + for(Bitu m=0;m<6;m++) { + if(addrptr[m]!=outbuffer[m+0xa])isloopback=false; + if(outbuffer[m+0xa]!=0xff) islocalbroadcast=false; + } + + if(!isloopback) { + outPacket.channel = UDPChannel; + outPacket.data = (Uint8 *)&outbuffer[0]; + outPacket.len = packetsize; + outPacket.maxlen = packetsize; + // Since we're using a channel, we won't send the IP address again + result = SDLNet_UDP_Send(ipxClientSocket, UDPChannel, &outPacket); + + if(result == 0) { + LOG_MSG("IPX: Could not send packet: %s", SDLNet_GetError()); + sendecb->setCompletionFlag(COMP_HARDWAREERROR); + sendecb->NotifyESR(); + DisconnectFromServer(true); + return; + } else { + sendecb->setCompletionFlag(COMP_SUCCESS); +#ifdef IPX_DEBUGMSG + LOG_MSG("Packet sent: size: %d",packetsize); +#endif + } + } + if(isloopback||islocalbroadcast) { + receivePacket(&outbuffer[0],packetsize); +#ifdef IPX_DEBUGMSG + LOG_MSG("Packet back: loopback:%d, broadcast:%d",isloopback,isbroadcast); +#endif + } + sendecb->NotifyESR(); +} static bool pingCheck(IPXHeader * outHeader) { char buffer[1024]; Bits result; UDPpacket regPacket; - IPXHeader *regHeader; regPacket.data = (Uint8 *)buffer; regPacket.maxlen = sizeof(buffer); @@ -766,8 +692,6 @@ static bool pingCheck(IPXHeader * outHeader) { return true; } return false; - - } bool ConnectToServer(char *strAddr) { @@ -776,7 +700,12 @@ bool ConnectToServer(char *strAddr) { IPXHeader regHeader; 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) { @@ -848,45 +777,21 @@ bool ConnectToServer(char *strAddr) { return false; } -void DisconnectFromServer(void) { +void IPX_NetworkInit() { - if(incomingPacket.connected) { - incomingPacket.connected = false; - TIMER_DelTickHandler(&IPX_ClientLoop); - SDLNet_UDP_Close(ipxClientSocket); - } -} - -bool IPX_NetworkInit() { - - localIpxAddr.netnum[0] = 0x0; localIpxAddr.netnum[1] = 0x0; localIpxAddr.netnum[2] = 0x0; localIpxAddr.netnum[3] = 0x1; - - /* - if(SDLNet_ResolveHost(&ipxClientIp, localhostname, tcpPort)) { - LOG_MSG("IPX: Unable to resolve localname: \"%s\". IPX disabled.", localhostname); - return false; - } else { - LOG_MSG("IPX: Using localname: %s IP is: %d.%d.%d.%d", localhostname, CONVIP(ipxClientIp.host)); - } - */ - - // 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 + localIpxAddr.netnum[0] = 0x0; + localIpxAddr.netnum[1] = 0x0; + localIpxAddr.netnum[2] = 0x0; + localIpxAddr.netnum[3] = 0x1; localIpxAddr.netnode[0] = 0x00; localIpxAddr.netnode[1] = 0x00; - //localIpxAddr.netnode[5] = (ipxClientIp.host >> 24) & 0xff; - //localIpxAddr.netnode[4] = (ipxClientIp.host >> 16) & 0xff; - //localIpxAddr.netnode[3] = (ipxClientIp.host >> 8) & 0xff; - //localIpxAddr.netnode[2] = (ipxClientIp.host & 0xff); - //To be filled in on response from server localIpxAddr.netnode[2] = 0x00; localIpxAddr.netnode[3] = 0x00; localIpxAddr.netnode[4] = 0x00; localIpxAddr.netnode[5] = 0x00; socketCount = 0; - return true; + return; } class IPXNET : public Program { @@ -1003,7 +908,7 @@ public: WriteOut("IPX Tunneling Server not running in this DosBox session.\n"); } else { isIpxServer = false; - DisconnectFromServer(); + DisconnectFromServer(false); IPX_StopServer(); WriteOut("IPX Tunneling Server stopped."); // Don't know how to stop the timer just yet. @@ -1044,7 +949,7 @@ public: // TODO: Send a packet to the server notifying of disconnect WriteOut("IPX Tunneling Client disconnected from server.\n"); - DisconnectFromServer(); + DisconnectFromServer(false); return; } @@ -1093,19 +998,6 @@ public: return; } } - - /* - WriteOut("IPX Status\n\n"); - if(!incomingPacket.connected) { - WriteOut("IPX tunneling client not presently connected"); - return; - } - if(isIpxServer) { - WriteOut("This DosBox session is an IPX tunneling server running on port %d", tcpPort); - } else { - WriteOut("This DosBox session is an IPX tunneling client connected to: %s",SDLNet_ResolveIP(&ipxServConnIp)); - } - */ } }; @@ -1126,17 +1018,12 @@ Bitu IPX_ESRHandler1(void) { SegSet16(es, RealSeg(ESRList->ECBAddr)); reg_si = RealOff(ESRList->ECBAddr); reg_al = 0xff; - CALLBACK_RunRealFar(RealSeg(ESRList->getESRAddr()), RealOff(ESRList->getESRAddr())); - delete ESRList; } // while -// PIC_DeActivateIRQ(11); IO_WriteB(0xa0,0x63); //EOI11 IO_WriteB(0x20,0x62); //EOI2 -// IO_WriteB(0xa0,0x20); //EOI - //IO_WriteB(0x20,0x20); //EOI #ifdef IPX_DEBUGMSG LOG_MSG("ESR loop done."); @@ -1192,14 +1079,12 @@ public: LOG_MSG("ESR callback address: %x, HandlerID %d", phyDospage,call_ipxesr1); #endif //save registers - phys_writeb(phyDospage+0,(Bit8u)0xFA); // CLI - phys_writeb(phyDospage+1,(Bit8u)0x60); // PUSHA - phys_writeb(phyDospage+2,(Bit8u)0x1E); // PUSH DS - phys_writeb(phyDospage+3,(Bit8u)0x06); // PUSH ES - phys_writeb(phyDospage+4,(Bit8u)0x0F); // PUSH.. - phys_writeb(phyDospage+5,(Bit8u)0xA0); // FS - phys_writeb(phyDospage+6,(Bit8u)0x0F); // PUSH.. - phys_writeb(phyDospage+7,(Bit8u)0xA8); // GS + phys_writeb(phyDospage+0,(Bit8u)0xFA); // CLI + phys_writeb(phyDospage+1,(Bit8u)0x60); // PUSHA + phys_writeb(phyDospage+2,(Bit8u)0x1E); // PUSH DS + phys_writeb(phyDospage+3,(Bit8u)0x06); // PUSH ES + phys_writew(phyDospage+4,(Bit16u)0xA00F); // PUSH FS + phys_writew(phyDospage+6,(Bit16u)0xA80F); // PUSH GS // callback phys_writeb(phyDospage+8,(Bit8u)0xFE); // GRP 4 @@ -1207,14 +1092,12 @@ public: phys_writew(phyDospage+10,call_ipxesr1); // Callback identifier // register recreation - phys_writeb(phyDospage+12,(Bit8u)0x0F);// POP.. - phys_writeb(phyDospage+13,(Bit8u)0xA9); // GS - phys_writeb(phyDospage+14,(Bit8u)0x0F);// POP.. - phys_writeb(phyDospage+15,(Bit8u)0xA1); // FS - phys_writeb(phyDospage+16,(Bit8u)0x07); // POP ES - phys_writeb(phyDospage+17,(Bit8u)0x1F); // POP DS - phys_writeb(phyDospage+18,(Bit8u)0x61); //POPA - phys_writeb(phyDospage+19,(Bit8u)0xCF); //IRET: restores flags, CS, IP + phys_writew(phyDospage+12,(Bit16u)0xA90F); // POP GS + phys_writew(phyDospage+14,(Bit16u)0xA10F); // POP FS + phys_writeb(phyDospage+16,(Bit8u)0x07); // POP ES + phys_writeb(phyDospage+17,(Bit8u)0x1F); // POP DS + phys_writeb(phyDospage+18,(Bit8u)0x61); // POPA + phys_writeb(phyDospage+19,(Bit8u)0xCF); // IRET: restores flags, CS, IP // IPX version 2.12 //phys_writeb(phyDospage+27,(Bit8u)0x2); @@ -1224,10 +1107,8 @@ public: RealPt ESRRoutineBase = RealMake(dospage, 0); // Interrupt enabling - RealSetVec(0x73,ESRRoutineBase,old_73_vector); // IRQ11 - Bit8u irqmask=IO_ReadB(0xa1); - irqmask &= ~8; // enable IRQ11 - IO_WriteB(0xa1,irqmask); + RealSetVec(0x73,ESRRoutineBase,old_73_vector); // IRQ11 + IO_WriteB(0xa1,IO_ReadB(0xa1)&(~8)); // enable IRQ11 PROGRAMS_MakeFile("IPXNET.COM",IPXNET_ProgramStart); } @@ -1238,16 +1119,13 @@ public: if(isIpxServer) { isIpxServer = false; - DisconnectFromServer(); IPX_StopServer(); } - disconnectServer(false); + DisconnectFromServer(false); DOS_DelMultiplexHandler(IPX_Multiplex); RealSetVec(0x73,old_73_vector); - Bit8u irqmask=IO_ReadB(0xa1); - irqmask |= 8; // disable IRQ11 - IO_WriteB(0xa1,irqmask); + IO_WriteB(0xa1,IO_ReadB(0xa1)|8); // disable IRQ11 PhysPt phyDospage = PhysMake(dospage,0); for(Bitu i = 0;i < 32;i++)