static void ipx_esr_call_irq(far_t ECBPtr, u_char AXVal) { if(in_dpmi_pm()) fake_pm_int(); fake_int_to(BIOSSEG, EOI_OFF); ipx_esr_call(ECBPtr, AXVal); }
int ipx_int7a(void) { u_short port; /* port here means DOS IPX socket */ u_short newPort; u_char *AddrPtr; far_t ECBPtr; unsigned long network; int hops, ticks; n_printf("IPX: request number 0x%x\n", LWORD(ebx)); switch (LWORD(ebx)) { case IPX_OPEN_SOCKET: if (LO(ax) != 0xff) n_printf("IPX: OpenSocket: longevity flag (%#x) not supported\n", LO(ax)); port = LWORD(edx); newPort = 0; LO(ax) = IPXOpenSocket(port, &newPort); if (LO(ax) == RCODE_SUCCESS) LWORD(edx) = newPort; break; case IPX_CLOSE_SOCKET: port = LWORD(edx); LO(ax) = IPXCloseSocket(port); break; case IPX_GET_LOCAL_TARGET: /* do nothing here because routing is handled by IPX */ /* normally this would return an ImmediateAddress, but */ /* the ECB ImmediateAddress is never used, so just return */ network = READ_DWORD(SEGOFF2LINEAR(REG(es), LWORD(esi))); n_printf("IPX: GetLocalTarget for network %08lx\n", network ); if( network==0 || memcmp(&network, MyAddress, 4) == 0 ) { n_printf("IPX: returning GLT success for local address\n"); LO(ax) = RCODE_SUCCESS; LWORD(ecx) = 1; } else { if( IPXGetLocalTarget( network, &hops, &ticks )==0 ) { LO(ax) = RCODE_SUCCESS; LWORD(ecx) = ticks; } else { n_printf("IPX: GetLocalTarget failed.\n"); LO(ax) = RCODE_CANNOT_FIND_ROUTE; } } break; case IPX_FAST_SEND: n_printf("IPX: fast send\n"); /* just fall through to regular send */ case IPX_SEND_PACKET: { int ret; ECBPtr.segment = REG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: send packet ECB at %p\n", ECBp); /* What the hell is the async send? Do it synchroniously! */ ret = IPXSendPacket(ECBPtr); if ((ret == RCODE_SUCCESS) && FARt_PTR(ECBp->ESRAddress)) ipx_esr_call(ECBPtr, ESR_CALLOUT_IPX); LO(ax) = ret; break; } case IPX_LISTEN_FOR_PACKET: ECBPtr.segment = REG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: listen for packet, ECB at %x:%x\n", ECBPtr.segment, ECBPtr.offset); /* put this packet on the queue of listens for this socket */ LO(ax) = IPXListenForPacket(ECBPtr); break; case IPX_SCHEDULE_IPX_EVENT: ECBPtr.segment = REG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: schedule IPX event for ECB at %x:%x\n", ECBPtr.segment, ECBPtr.offset); /* put this packet on the queue of AES events for this socket */ LO(ax) = IPXScheduleEvent(ECBPtr, IU_ECB_IPX_WAITING, LWORD(eax)); break; case IPX_CANCEL_EVENT: ECBPtr.segment = REG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: cancel event for ECB at %p\n", ECBp); LO(ax) = IPXCancelEvent(ECBPtr); break; case IPX_SCHEDULE_AES_EVENT: ECBPtr.segment = REG(es); ECBPtr.offset = LWORD(esi); n_printf("IPX: schedule AES event ECB at %p\n", FARt_PTR(ECBPtr)); /* put this packet on the queue of AES events for this socket */ LO(ax) = IPXScheduleEvent(ECBPtr, IU_ECB_AES_WAITING, LWORD(eax)); break; case IPX_GET_INTERVAL_MARKER: /* Note that timerticks is actually an unsigned long in BIOS */ /* this works because of intel lo-hi architecture */ LWORD(eax) = READ_WORD(BIOS_TICK_ADDR); n_printf("IPX: get interval marker %d\n", LWORD(eax)); /* n_printf("IPX: doing extra relinquish control\n"); */ IPXRelinquishControl(); break; case IPX_GET_INTERNETWORK_ADDRESS: n_printf("IPX: get internetwork address\n"); AddrPtr = SEG_ADR((u_char *), es, si); memcpy(AddrPtr, MyAddress, 10); break; case IPX_RELINQUISH_CONTROL: n_printf("IPX: relinquish control\n"); IPXRelinquishControl(); break; case IPX_DISCONNECT: n_printf("IPX: disconnect\n"); break; case IPX_SHELL_HOOK: n_printf("IPX: shell hook\n"); break; case IPX_GET_MAX_PACKET_SIZE: n_printf("IPX: get max packet size\n"); /* return max data size in AX, and suggested retries in CL */ /* DANG_FIXTHIS - return a real max packet size here */ LWORD(eax) = 1024; /* must be a power of 2 */ LO(cx) = 20; break; case IPX_GET_MEDIA_DATA_SIZE: n_printf("IPX: get max packet size\n"); /* return max data size in AX, and suggested retries in CL */ /* DANG_FIXTHIS - return a real max media size here */ LWORD(eax) = 1480; LO(cx) = 20; break; case IPX_CLEAR_SOCKET: n_printf("IPX: clear socket\n"); break; default: n_printf("IPX: Unimplemented function.\n"); break; } return 1; }
static void ipx_aes_esr_call_thr(void *arg) { n_printf("IPX: Calling AES ESR\n"); ipx_esr_call(aesECB, ESR_CALLOUT_AES); }
static void ipx_recv_esr_call_thr(void *arg) { n_printf("IPX: Calling receive ESR\n"); ipx_esr_call(recvECB, ESR_CALLOUT_IPX); }