Subversion Repositories pentevo

Rev

Rev 1088 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "std.h"
  2. #include "emul.h"
  3. #include "vars.h"
  4. #include "zxusbnet.h"
  5. #include <iphlpapi.h>
  6.  
  7. #define buf_size 8*1024
  8.  
  9. //#define dbgmod
  10. #ifdef dbgmod
  11. #define DPRINTF printf
  12. #else
  13. #define DPRINTF(pa,pb)
  14. #endif // dbgmod
  15.  
  16. #define WRITE_REG_FUNC(f_n) void f_n(sInfoStruct * s, u_char d, u_char z)
  17. #define READ_REG_FUNC(f_n) u_char f_n(sInfoStruct * s, u_char z)
  18.  
  19.  
  20. enum class TCP_STATE{
  21.         NONE, CLIENT_CONNECTED, LISTEN_CONNECTED, CLIENT, LISTEN, CLOSED
  22. };
  23.  
  24. /************************************/
  25. /* The bit of MR regsiter defintion */
  26. /************************************/
  27. #define MR_DBW             (1 << 15)            /**< Data bus width bit of MR. */
  28. #define MR_MPF             (1 << 14)            /**< Mac layer pause frame bit of MR. */
  29. #define MR_WDF(X)          ((X & 0x07) << 11)   /**< Write data fetch time bit of  MR. */
  30. #define MR_RDH             (1 << 10)            /**< Read data hold time bit of MR. */
  31. #define MR_FS              (1 << 8)             /**< FIFO swap bit of MR. */
  32. #define MR_RST             (1 << 7)             /**< S/W reset bit of MR. */
  33. #define MR_MT              (1 << 5)             /**< Memory test bit of MR. */
  34. #define MR_PB              (1 << 4)             /**< Ping block bit of MR. */
  35. #define MR_PPPoE           (1 << 3)             /**< PPPoE bit of MR. */
  36. #define MR_DBS             (1 << 2)             /**< Data bus swap of MR. */
  37. #define MR_IND             (1 << 0)             /**< Indirect mode bit of MR. */
  38.  
  39.  
  40. /***************************************/
  41. /* The bit of Sn_MR regsiter defintion */
  42. /***************************************/
  43. #define Sn_MR_ALIGN        (1 << 8)             /**< Alignment bit of Sn_MR. */
  44. #define Sn_MR_MULTI        (1 << 7)             /**< Multicasting bit of Sn_MR. */
  45. #define Sn_MR_MF           (1 << 6)             /**< MAC filter bit of Sn_MR. */
  46. #define Sn_MR_IGMPv        (1 << 5)             /**< IGMP version bit of Sn_MR. */
  47. #define Sn_MR_ND           (1 << 5)             /**< No delayed ack bit of Sn_MR. */
  48. #define Sn_MR_CLOSE        0x00                 /**< Protocol bits of Sn_MR. */
  49. #define Sn_MR_TCP          0x01                 /**< Protocol bits of Sn_MR. */
  50. #define Sn_MR_UDP          0x02                 /**< Protocol bits of Sn_MR. */
  51. #define Sn_MR_IPRAW        0x03                 /**< Protocol bits of Sn_MR. */
  52. #define Sn_MR_MACRAW       0x04                 /**< Protocol bits of Sn_MR. */
  53. #define Sn_MR_PPPoE        0x05                 /**< Protocol bits of Sn_MR. */
  54.  
  55. /******************************/
  56. /* The values of CR defintion */
  57. /******************************/
  58. #define Sn_CR_OPEN         0x01                 /**< OPEN command value of Sn_CR. */
  59. #define Sn_CR_LISTEN       0x02                 /**< LISTEN command value of Sn_CR. */
  60. #define Sn_CR_CONNECT      0x04                 /**< CONNECT command value of Sn_CR. */
  61. #define Sn_CR_DISCON       0x08                 /**< DISCONNECT command value of Sn_CR. */
  62. #define Sn_CR_CLOSE        0x10                 /**< CLOSE command value of Sn_CR. */
  63. #define Sn_CR_SEND         0x20                 /**< SEND command value of Sn_CR. */
  64. #define Sn_CR_SEND_MAC     0x21                 /**< SEND_MAC command value of Sn_CR. */
  65. #define Sn_CR_SEND_KEEP    0x22                 /**< SEND_KEEP command value of Sn_CR */
  66. #define Sn_CR_RECV         0x40                 /**< RECV command value of Sn_CR */
  67. #define Sn_CR_PCON         0x23                 /**< PCON command value of Sn_CR */
  68. #define Sn_CR_PDISCON      0x24                 /**< PDISCON command value of Sn_CR */
  69. #define Sn_CR_PCR          0x25                 /**< PCR command value of Sn_CR */
  70. #define Sn_CR_PCN          0x26                 /**< PCN command value of Sn_CR */
  71. #define Sn_CR_PCJ          0x27                 /**< PCJ command value of Sn_CR */
  72.  
  73. /**********************************/
  74. /* The values of Sn_SSR defintion */
  75. /**********************************/
  76. #define SOCK_CLOSED        0x00                 /**< SOCKETn is released */
  77. #define SOCK_ARP           0x01                 /**< ARP-request is transmitted in order to acquire destination hardware address. */
  78. #define SOCK_INIT          0x13                 /**< SOCKETn is open as TCP mode. */
  79. #define SOCK_LISTEN        0x14                 /**< SOCKETn operates as "TCP SERVER" and waits for connection-request (SYN packet) from "TCP CLIENT". */
  80. #define SOCK_SYNSENT       0x15                 /**< Connect-request(SYN packet) is transmitted to "TCP SERVER". */
  81. #define SOCK_SYNRECV       0x16                 /**< Connect-request(SYN packet) is received from "TCP CLIENT". */
  82. #define SOCK_ESTABLISHED   0x17                 /**< TCP connection is established. */
  83. #define SOCK_FIN_WAIT      0x18                 /**< SOCKETn is closing. */
  84. #define SOCK_CLOSING       0x1A                 /**< SOCKETn is closing. */
  85. #define SOCK_TIME_WAIT     0x1B                 /**< SOCKETn is closing. */
  86. #define SOCK_CLOSE_WAIT    0x1C                 /**< Disconnect-request(FIN packet) is received from the peer. */
  87. #define SOCK_LAST_ACK      0x1D                 /**< SOCKETn is closing. */
  88. #define SOCK_UDP           0x22                 /**< SOCKETn is open as UDP mode. */
  89. #define SOCK_IPRAW         0x32                 /**< SOCKETn is open as IPRAW mode. */
  90. #define SOCK_MACRAW        0x42                 /**< SOCKET0 is open as MACRAW mode. */
  91. #define SOCK_PPPoE         0x5F                 /**< SOCKET0 is open as PPPoE mode. */
  92.  
  93.  
  94. union LONG_CHAR{
  95.         u_long ul;
  96.         u_char b[4];
  97. };
  98.  
  99.  
  100. static struct sInfoStruct
  101. {
  102.         SOCKET s; //socket
  103.         sockaddr_in sa_in;
  104.         u_char PORTR[2];
  105.         WSAEVENT Event;
  106.         u_char MR[2];
  107.         u_char CR;
  108.         TCP_STATE tcpState;
  109.         u_long RX_RSR;
  110.         u_char rx[buf_size + 8];
  111.         u_char * rx_ptr;
  112.         LONG_CHAR TX_WRSR;
  113.         u_char tx[buf_size];
  114.         u_char * tx_ptr;
  115.         SOCKET list; //socket
  116.         u_char PROTOR;
  117.         u_char BINDED;
  118. }soc[8];
  119. //static char myIP[4];
  120. static sockaddr_in sa_in;
  121. static sockaddr_in r_sa_in;
  122. //static u_long len_test;
  123. static TIMEVAL select_timeout;
  124. static u_char stat_regs[0x0100];
  125. static u_char regs[sizeof(stat_regs)];
  126. static int ns, iResult;
  127. static u_char data;
  128. //static char * s_ptr;
  129. static fd_set fd_s;
  130. //static fd_set fd_s1;
  131. static u_long is_blocked = 0, non_blocked = 1;
  132. WSADATA wsaData;
  133.  
  134. void soc_bind(sInfoStruct * s){
  135.         ZeroMemory(&sa_in, sizeof(sa_in));
  136.         sa_in.sin_family = AF_INET;
  137.         //memcpy(&sa_in.sin_addr.S_un.S_addr, &stat_regs[0x0018], 4);
  138.         char broadcast = '1';
  139.         setsockopt(s->s,SOL_SOCKET,SO_BROADCAST,&broadcast,sizeof(broadcast));
  140.         sa_in.sin_addr.s_addr = htonl(INADDR_ANY);;
  141.         sa_in.sin_port = (s->PORTR[1] << 8) | s->PORTR[0];
  142.         bind(s->s, (sockaddr *)&sa_in, sizeof(sa_in));
  143.         s->BINDED = 1;
  144. }
  145.  
  146. void WizRecv(sInfoStruct * s){
  147.         if (s->rx_ptr)return;
  148.         int len=0;
  149.         switch (s->MR[1]){
  150.                 case Sn_MR_TCP:
  151.                         len = recv(s->s, (char*)&s->rx[2], buf_size, 0);
  152.                         break;
  153.                 case Sn_MR_UDP:
  154.                         if(s->BINDED == 0) soc_bind(s);
  155.                         //ZeroMemory(&r_sa_in, sizeof(r_sa_in));
  156.                         iResult = sizeof(r_sa_in);
  157.                         len=recvfrom(s->s, (char*)&s->rx[8], buf_size, 0, (sockaddr *)&r_sa_in, &iResult);
  158.                         break; 
  159.                 case Sn_MR_IPRAW:
  160.                         if(s->BINDED == 0) soc_bind(s);
  161.                         //ZeroMemory(&r_sa_in, sizeof(r_sa_in));
  162.                         iResult = sizeof(r_sa_in);
  163.                         len=recvfrom(s->s, (char*)&s->rx[6], buf_size, 0, (sockaddr *)&r_sa_in, &iResult);
  164.                         //printf("res=%d, errno=%d\r\n",len,errno);
  165.                         break; 
  166.         }
  167.         if(len>0)DPRINTF("Recv %d bytes\r\n", len);
  168.         switch (len)
  169.         {
  170.         case -1:
  171.                 return;
  172.         case 0:
  173.                 if (s->MR[1] == Sn_MR_TCP)
  174.                         s->tcpState = TCP_STATE::CLOSED;
  175.                 return;
  176.         default:
  177.                 break;
  178.         }
  179.         //unsigned char * p = s->rx;
  180.         switch (s->MR[1]){
  181.                 case Sn_MR_TCP:
  182.                         s->rx[0] = (len & 0xff00) >> 8;
  183.                         s->rx[1] = len & 0x00ff;
  184.                         s->RX_RSR = (len + 3) & 0x0001fffe;
  185.                         break;
  186.                 case Sn_MR_UDP:
  187.                         *((ULONG*)s->rx) = r_sa_in.sin_addr.S_un.S_addr;
  188.                         *((u_short*)&s->rx[4]) = r_sa_in.sin_port;
  189.                         s->rx[6] = (len & 0xff00) >> 8;
  190.                         s->rx[7] = len & 0x00ff;
  191.                         s->RX_RSR = (len + 9) & 0x0001fffe;
  192.                         break; 
  193.                 case Sn_MR_IPRAW:
  194.                         *((ULONG*)s->rx) = r_sa_in.sin_addr.S_un.S_addr;
  195.                         s->rx[4] = (len & 0xff00) >> 8;
  196.                         s->rx[5] = len & 0x00ff;
  197.                         s->RX_RSR = (len + 7) & 0x0001fffe;
  198.                         break; 
  199.         }
  200.         s->rx_ptr = s->rx;
  201. }
  202.  
  203. READ_REG_FUNC(read_MR){ return s->MR[z]; }
  204.  
  205. READ_REG_FUNC(read_CR){
  206.         if (!s->CR)return 0;
  207.         if (s->s == INVALID_SOCKET)return s->CR;
  208.         return 0;
  209. }
  210.  
  211. READ_REG_FUNC(read_SSR){
  212.         if (s->s == INVALID_SOCKET || s->tcpState == TCP_STATE::CLOSED)
  213.                 return SOCK_CLOSED;
  214.         if (s->MR[1] == Sn_MR_TCP && s->tcpState == TCP_STATE::NONE){
  215.                 return SOCK_INIT;
  216.         }
  217.         FD_ZERO(&fd_s);
  218.         FD_SET(s->s, &fd_s);
  219.         iResult = select(0, NULL, NULL, &fd_s, &select_timeout);
  220.         if (iResult == SOCKET_ERROR)
  221.                 return SOCK_CLOSED;
  222.         if (s->tcpState == TCP_STATE::LISTEN){
  223.                 s->list = accept(s->s, (sockaddr *)&s->sa_in, &ns);
  224.                 if (s->list != (unsigned int)SOCKET_ERROR){
  225.                         ioctlsocket(s->s, FIONBIO, &is_blocked);
  226.                         closesocket(s->s);
  227.                         s->s = s->list;
  228.                         ioctlsocket(s->s, FIONBIO, &non_blocked);
  229.                         bool bOptVal = true;
  230.                         setsockopt(s->s, SOL_SOCKET, SO_KEEPALIVE, (char*)bOptVal, sizeof(bOptVal));
  231.                         s->tcpState = TCP_STATE::LISTEN_CONNECTED;
  232.                         return SOCK_ESTABLISHED;
  233.                 }
  234.                 return SOCK_LISTEN;
  235.         }
  236.         FD_ZERO(&fd_s);
  237.         FD_SET(s->s, &fd_s);
  238.         iResult = select(0, NULL, &fd_s, NULL, &select_timeout);
  239.         if (iResult == SOCKET_ERROR)
  240.                 return SOCK_CLOSED;
  241.         if (iResult == 0){
  242.                 switch (s->MR[1])
  243.                 {
  244.                 case Sn_MR_TCP:
  245.                         switch (s->tcpState)
  246.                         {
  247.                         case TCP_STATE::LISTEN_CONNECTED:
  248.                         case TCP_STATE::CLIENT_CONNECTED:
  249.                                 return SOCK_ESTABLISHED;
  250.                         default:
  251.                                 FD_ZERO(&fd_s);
  252.                                 FD_SET(s->s, &fd_s);
  253.                                 iResult = select(0, NULL, NULL, &fd_s, &select_timeout);
  254.                                 if (iResult != 0){
  255.                                         s->tcpState = TCP_STATE::CLOSED;
  256.                                         return SOCK_CLOSED;
  257.                                 }
  258.                                 return SOCK_INIT;
  259.                         }
  260.                 case Sn_MR_UDP:
  261.                         return SOCK_UDP;
  262.                 case Sn_MR_IPRAW:
  263.                         return SOCK_IPRAW;
  264.                 default:
  265.                         return SOCK_CLOSED;
  266.                 }
  267.         }
  268.         else if (iResult > 0){
  269.                 FD_ZERO(&fd_s);
  270.                 FD_SET(s->s, &fd_s);
  271.                 iResult = select(0, NULL, NULL, &fd_s, &select_timeout);
  272.                 if (iResult != 0){
  273.                         s->tcpState = TCP_STATE::CLOSED;
  274.                         return SOCK_CLOSED;
  275.                 }
  276.                 switch (s->MR[1])
  277.                 {
  278.                 case Sn_MR_TCP:
  279.                         switch (s->tcpState)
  280.                         {
  281.                         case TCP_STATE::LISTEN:
  282.                                 s->tcpState = TCP_STATE::LISTEN_CONNECTED;
  283.                                 return SOCK_ESTABLISHED;
  284.                         case TCP_STATE::CLIENT:
  285.                                 s->tcpState = TCP_STATE::CLIENT_CONNECTED;
  286.                                 return SOCK_ESTABLISHED;
  287.                         case TCP_STATE::CLOSED:
  288.                                 return SOCK_CLOSED;
  289.                         }
  290.                         WizRecv(s);
  291.                         if (s->tcpState == TCP_STATE::CLOSED) return SOCK_CLOSED;
  292.                         return SOCK_ESTABLISHED;
  293.                 case Sn_MR_UDP:
  294.                         return SOCK_UDP;
  295.                 case Sn_MR_IPRAW:
  296.                         return SOCK_IPRAW;
  297.                 default:
  298.                         return SOCK_CLOSED;
  299.                 }
  300.         }
  301.         //ns = WSAGetLastError();
  302.         return SOCK_CLOSED;
  303. }
  304.  
  305. READ_REG_FUNC(read_PORTR){
  306.         return s->PORTR[z];
  307. }
  308.  
  309. READ_REG_FUNC(read_DPORTR){
  310.         if (z) return (s->sa_in.sin_port & 0xff00) >> 8;
  311.         else return s->sa_in.sin_port & 0x00ff;
  312. }
  313.  
  314. READ_REG_FUNC(read_ZERO){
  315.         return 0;
  316. }
  317.  
  318. READ_REG_FUNC(read_DIPR12){
  319.         if (!z)
  320.                 return s->sa_in.sin_addr.S_un.S_un_b.s_b1;
  321.         else
  322.                 return s->sa_in.sin_addr.S_un.S_un_b.s_b2;
  323. }
  324.  
  325. READ_REG_FUNC(read_DIPR34){
  326.         if (!z)
  327.                 return s->sa_in.sin_addr.S_un.S_un_b.s_b3;
  328.         else
  329.                 return s->sa_in.sin_addr.S_un.S_un_b.s_b4;
  330. }
  331.  
  332. READ_REG_FUNC(read_PROTOR){
  333.         if (!z)
  334.                 return 0x00;
  335.         else
  336.                 return s->PROTOR;
  337. }
  338.  
  339. READ_REG_FUNC(read_TX_FSR32){
  340.         if (z == 0) return 0;
  341.         return ((sizeof(s->tx) - ((u_int)(s->tx_ptr - s->tx))) & 0x00010000) >> 16;
  342. }
  343.  
  344. READ_REG_FUNC(read_TX_FSR10){
  345.         if (z == 0) return ((sizeof(s->tx) - ((u_int)(s->tx_ptr - s->tx))) & 0x0000ff00) >> 8;
  346.         return (sizeof(s->tx) - ((u_int)(s->tx_ptr - s->tx))) & 0x000000fF;
  347. }
  348.  
  349. READ_REG_FUNC(read_RX_RSR32){
  350.         if (s->s == INVALID_SOCKET)return 0;
  351.         if (z == 0) return 0;
  352.         WizRecv(s);
  353.         return (u_char)((s->RX_RSR & 0x00010000) >> 16);
  354. }
  355.  
  356. READ_REG_FUNC(read_RX_RSR10){
  357.         if (s->s == INVALID_SOCKET)return 0;
  358.         WizRecv(s);
  359.         if (z == 0) return (s->RX_RSR & 0x0000ff00) >> 8;
  360.         return s->RX_RSR & 0x000000fF;
  361. }
  362.  
  363. READ_REG_FUNC(read_RX){
  364.         if (s->RX_RSR == 0)return 0;
  365.         data = *(s->rx_ptr + z);
  366.         if (z == 0)return data;
  367.         s->RX_RSR -= 2;
  368.         if (s->RX_RSR == 0)
  369.                 s->rx_ptr = NULL;
  370.         else
  371.                 s->rx_ptr += 2;
  372.         return data;
  373. }
  374.  
  375. u_char(*regReadFunc[0x20])(sInfoStruct *, u_char) = {
  376.         read_MR, read_CR, read_ZERO, read_ZERO, read_SSR, read_PORTR, read_ZERO, read_ZERO,
  377.         read_ZERO, read_DPORTR, read_DIPR12, read_DIPR34, read_ZERO, read_PROTOR, read_ZERO, read_ZERO,
  378.         read_ZERO, read_ZERO, read_TX_FSR32, read_TX_FSR10, read_RX_RSR32, read_RX_RSR10, read_ZERO, read_ZERO,
  379.         read_RX, read_ZERO, read_ZERO, read_ZERO, read_ZERO, read_ZERO, read_ZERO, read_ZERO,
  380. };
  381. void WIZ_CLOSE_SOC(sInfoStruct * s){
  382.         if (s->s != INVALID_SOCKET){
  383.                 ioctlsocket(s->s, FIONBIO, &is_blocked);
  384.                 iResult = closesocket(s->s);
  385.                 DPRINTF("closesocket = %x", iResult);
  386.                 s->s = INVALID_SOCKET;
  387.                 s->PROTOR = 0x00;
  388.         }
  389. }
  390.  
  391. void WizOpenSocket(sInfoStruct * s){
  392.         bool bOptVal = true;
  393.         DWORD tout = 3000;
  394.         if (s->s != INVALID_SOCKET) return;
  395.         s->RX_RSR = 0;
  396.         memset(&s->sa_in.sin_addr,0x00,sizeof(s->sa_in.sin_addr));
  397.         s->sa_in.sin_family = AF_INET;
  398.         s->rx_ptr = NULL;
  399.         s->tx_ptr = s->tx;
  400.         s->tcpState = TCP_STATE::NONE;
  401.         s->BINDED = 0;
  402.         switch (s->MR[1])
  403.         {
  404.         case Sn_MR_TCP:
  405.                 s->s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  406.                 setsockopt(s->s, SOL_SOCKET, SO_KEEPALIVE, (char*)&bOptVal, sizeof(bOptVal));
  407.                 DPRINTF("Opensocket %u ", s->s);
  408.                 break;
  409.         case Sn_MR_UDP:
  410.                 s->s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  411.                 break;
  412.         case Sn_MR_IPRAW:
  413.                 setsockopt(s->s, SOL_SOCKET, SO_RCVTIMEO, (char*)&tout, sizeof(tout));
  414.                 s->s = socket(AF_INET, SOCK_RAW, s->PROTOR);
  415.                 break;
  416.         default:
  417.                 s->s = INVALID_SOCKET;
  418.                 break;
  419.         }
  420.         if (s->s != INVALID_SOCKET){
  421.                 ioctlsocket(s->s, FIONBIO, &non_blocked);
  422.                 s->CR = 0;
  423.         }
  424. }
  425.  
  426. void WizConnect(sInfoStruct *s){
  427.         if (s->MR[1] != Sn_MR_TCP || s->s == INVALID_SOCKET || s->tcpState != TCP_STATE::NONE) return;
  428.         s->CR = 0;
  429.         s->tcpState = TCP_STATE::CLIENT;
  430.         connect(s->s, (SOCKADDR *)&s->sa_in, sizeof(s->sa_in));
  431. }
  432.  
  433. void WisDisconnect(sInfoStruct *s){
  434.         if (s->MR[1] != Sn_MR_TCP) return;
  435. }
  436.  
  437. void WisListen(sInfoStruct *s){
  438.         if (s->MR[1] != Sn_MR_TCP || s->s == INVALID_SOCKET || s->tcpState != TCP_STATE::NONE) return;
  439.         s->tcpState = TCP_STATE::LISTEN;
  440.         ZeroMemory(&sa_in, sizeof(sa_in));
  441.         //s->list = s->s;
  442.         sa_in.sin_family = AF_INET;
  443.         sa_in.sin_addr.S_un.S_addr = 0;
  444.         sa_in.sin_port = (s->PORTR[1] << 8) | s->PORTR[0];
  445.         bind(s->s, (sockaddr *)&sa_in, sizeof(sa_in));
  446.         s->BINDED = 1;
  447.         listen(s->s, 1);
  448.         ns = sizeof(s->sa_in);
  449. }
  450.  
  451. void WizSend(sInfoStruct *s){
  452.         if (s->s == INVALID_SOCKET)return;
  453.         iResult = (int)(s->TX_WRSR.ul & 0x01ffff);
  454.         if (s->MR[1] == Sn_MR_TCP && s->tcpState != TCP_STATE::NONE){
  455.                 send(s->s, (char*)s->tx, (int)(s->TX_WRSR.ul & 0x01ffff), 0);
  456.                 s->tx_ptr = s->tx;
  457.                 s->TX_WRSR.ul = 0;
  458.                 DPRINTF("Send %d bytes\r\n", iResult);
  459.         }
  460.         else if ((s->MR[1] == Sn_MR_UDP) || (s->MR[1] == Sn_MR_IPRAW)){
  461.                 if(s->BINDED == 0) soc_bind(s);
  462.                 sendto(s->s, (char*)s->tx, (int)(s->TX_WRSR.ul & 0x01ffff), 0, (sockaddr *)&s->sa_in, sizeof(sa_in));
  463.                 s->tx_ptr = s->tx;
  464.                 s->TX_WRSR.ul = 0;
  465.                 DPRINTF("Send %d bytes\r\n", iResult);
  466.         }
  467. }
  468.  
  469. WRITE_REG_FUNC(write_DPORTR){
  470.         if (z) s->sa_in.sin_port = ((s->sa_in.sin_port) & 0x00ff) | (d << 8);
  471.         else s->sa_in.sin_port = ((s->sa_in.sin_port) & 0xff00) | d;
  472. };
  473.  
  474. WRITE_REG_FUNC(write_MR){
  475.         WIZ_CLOSE_SOC(s);
  476.         s->MR[z] = d;
  477. };
  478.  
  479. WRITE_REG_FUNC(write_CR){
  480.         if (!z)return;
  481.         DPRINTF("Write CR = %x\r\n", d);
  482.         s->CR = d;
  483.         switch (d)
  484.         {
  485.         case Sn_CR_CLOSE:
  486.                 WIZ_CLOSE_SOC(s);
  487.                 s->CR = 0;
  488.                 break;
  489.         case Sn_CR_RECV:
  490.                 s->rx_ptr = NULL;
  491.                 s->RX_RSR = 0;
  492.                 s->CR = 0;
  493.                 break;
  494.         case Sn_CR_SEND:
  495.                 WizSend(s);
  496.                 break;
  497.         case Sn_CR_DISCON:
  498.                 if (s->s != INVALID_SOCKET){
  499.                         WIZ_CLOSE_SOC(s);
  500.                         //WizOpenSocket(s);
  501.                         s->CR = 0;
  502.                 }
  503.                 break;
  504.         case Sn_CR_OPEN:
  505.                 WizOpenSocket(s);
  506.                 break;
  507.         case Sn_CR_LISTEN:
  508.                 WisListen(s);
  509.                 break;
  510.         case Sn_CR_CONNECT:
  511.                 WizConnect(s);
  512.                 break;
  513.         default:
  514.                 break;
  515.         }
  516. };
  517.  
  518. WRITE_REG_FUNC(write_PORTR){
  519.         s->PORTR[z] = d;
  520. };
  521.  
  522. WRITE_REG_FUNC(write_DIPR12){
  523.         if (!z)s->sa_in.sin_addr.S_un.S_un_b.s_b1 = d;
  524.         else s->sa_in.sin_addr.S_un.S_un_b.s_b2 = d;
  525. }
  526.  
  527. WRITE_REG_FUNC(write_DIPR34){
  528.         if (!z)s->sa_in.sin_addr.S_un.S_un_b.s_b3 = d;
  529.         else s->sa_in.sin_addr.S_un.S_un_b.s_b4 = d;
  530. }
  531.  
  532. WRITE_REG_FUNC(write_PROTOR){
  533.         if (z)s->PROTOR = d;
  534. }
  535.  
  536. WRITE_REG_FUNC(write_TX_WRSR32){
  537.         s->TX_WRSR.b[3 - z] = d;
  538. };
  539.  
  540. WRITE_REG_FUNC(write_TX_WRSR10){
  541.         s->TX_WRSR.b[1 - z] = d;
  542. };
  543.  
  544. WRITE_REG_FUNC(write_TX){
  545.         *(s->tx_ptr + z) = d;
  546.         if (z == 0)return;
  547.         s->tx_ptr += 2;
  548. };
  549.  
  550. WRITE_REG_FUNC(write_ZERO){};
  551.  
  552. void(*regWriteFunc[0x20])(sInfoStruct * s, u_char, u_char) = {
  553.         write_MR, write_CR, write_ZERO, write_ZERO, write_ZERO, write_PORTR, write_ZERO, write_ZERO,
  554.         write_ZERO, write_DPORTR, write_DIPR12, write_DIPR34, write_ZERO, write_PROTOR, write_ZERO, write_ZERO,
  555.         write_TX_WRSR32, write_TX_WRSR10, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_TX,
  556.         write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO,
  557. };
  558.  
  559. u_char Wiz5300_RegRead(unsigned int Addr)
  560. {
  561.  
  562.         if(comp.wiznet.p82&0x08)Addr^=0x01;
  563.         if (Addr >= 0x0200)
  564.                 return regReadFunc[(Addr & 0x3f) >> 1](&soc[(Addr >> 6) & 0x07], Addr & 0x01);
  565.         if (Addr <= 0x00ff){
  566.                 return regs[Addr];
  567.         }
  568.         return 0;
  569. }
  570.  
  571. void Wiz5300_RegWrite(unsigned int Addr, unsigned char Data)
  572. {
  573.         if(comp.wiznet.p82&0x08)Addr^=0x01;
  574.         if (Addr >= 0x0200)
  575.                 regWriteFunc[(Addr & 0x3f) >> 1](&soc[(Addr >> 6) & 0x07], Data, Addr & 0x01);
  576.         else if (Addr <= 0x00ff) {
  577.                 regs[Addr] = stat_regs[Addr];
  578.         }
  579. }
  580.  
  581. void getNetProperties(void){
  582.         char ac[80];
  583.         gethostname(ac, sizeof(ac));
  584.         struct hostent *phe = gethostbyname(ac);
  585.         if (phe)memcpy(&stat_regs[0x0018], phe->h_addr_list[0], 4);
  586.         if (*((ULONG32*)(&stat_regs[0x0018])) == 0)return;
  587.  
  588.         PIP_ADAPTER_INFO pAdapterInfo, pAdapter = NULL;
  589.         DWORD dwRetVal = 0;
  590.         //unsigned int i;
  591.         //struct tm newtime;
  592.         //errno_t error;
  593.         ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
  594.         pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
  595.         // if (pAdapterInfo==NULL) ...return
  596.         if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW){
  597.                 free(pAdapterInfo);
  598.                 pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
  599.                 // if (pAdapterInfo==NULL) ...return
  600.         }
  601.         if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR){
  602.                 pAdapter = pAdapterInfo;
  603.                 while (pAdapter)
  604.                 {
  605.                         if (pAdapter->IpAddressList.Context != *((DWORD32*)(&stat_regs[0x0018]))){
  606.                                 pAdapter = pAdapter->Next;
  607.                                 continue;
  608.                         }
  609.                         printf("Network adapter: %s \r\n",pAdapter->Description);
  610.                         *((ULONG32*)(&stat_regs[0x0014])) = inet_addr(pAdapter->IpAddressList.IpMask.String);
  611.                         *((ULONG32*)(&stat_regs[0x0010])) = inet_addr(pAdapter->GatewayList.IpAddress.String);
  612.                         memcpy(&stat_regs[0x008], pAdapter->Address, 8);
  613.                         break;
  614.                 }
  615.         }
  616.         else
  617.         {
  618.                 //print error, no return
  619.         }
  620.         if (pAdapterInfo){
  621.                 free(pAdapterInfo);
  622.         }
  623. }
  624.  
  625. int Wiz5300_Init(void)
  626. {
  627.         ZeroMemory(stat_regs, sizeof(stat_regs));
  628.         memset(&stat_regs[0x20], 0x08, 16);
  629.         stat_regs[0x00] = 0x38;
  630.         stat_regs[0xfe] = 0x53;
  631.         stat_regs[0x31] = 0xff;
  632.         memcpy(regs, stat_regs, sizeof(stat_regs));
  633.  
  634.         ZeroMemory(soc, sizeof(soc));
  635.         WSAStartup(MAKEWORD(2, 2), &wsaData);
  636.         for (int i = 0; i < 8; i++){
  637.                 soc[i].s = INVALID_SOCKET;
  638.                 soc[i].sa_in.sin_family = AF_INET;
  639.                 soc[i].list = INVALID_SOCKET;
  640.                 soc[i].PROTOR = 0x00;
  641.         }
  642.         select_timeout.tv_sec = 0;
  643.         select_timeout.tv_usec = 0;
  644.         getNetProperties();
  645.         //DPRINTF("wiz init\r\n");
  646.         return 0;
  647. }
  648.  
  649. int Wiz5300_Close(void)
  650. {
  651.         for (int i = 0; i < 8; i++) {
  652.                 if (soc[i].s != INVALID_SOCKET){
  653.                         ioctlsocket(soc[i].s, FIONBIO, &is_blocked);
  654.                         closesocket(soc[i].s);
  655.                 }
  656.         }
  657.         WSACleanup(); //Clean up Winsock
  658.         return 0;
  659. }
  660.  
  661.  
  662. void pXXAB_Write(unsigned port, unsigned char val){
  663.         if((!(port&0x8000))&&(comp.wiznet.p82&0x10)){
  664.                 Wiz5300_RegWrite(((comp.wiznet.p81&0x0f)<<6)|
  665.                         ((port&0x3f00)>>8),val);
  666.                 return;
  667.         }
  668.         if(port==0x83ab){
  669.                 if((comp.wiznet.p83&0x10)^(val&0x10)){
  670.                         if(val&0x10){Wiz5300_Init();}
  671.                         else {Wiz5300_Close();}
  672.                 }
  673.                 comp.wiznet.p83=val;
  674.                
  675.         }else if(port==0x82ab){
  676.                 comp.wiznet.p82=val;
  677.         }else if(port==0x81ab){
  678.                 comp.wiznet.p81=val;
  679.                 return;
  680.         }
  681.         comp.wiznet.memEna=conf.wiznet && (comp.wiznet.p82 & 0x04)
  682.                 && (comp.wiznet.p83 & 0x10) && (!(comp.wiznet.p82 & 0x10));
  683.         return;
  684. }
  685.  
  686. unsigned char pXXAB_Read(unsigned port){
  687.         if((!(port&0x8000))&&(comp.wiznet.p82&0x10)){
  688.                 return Wiz5300_RegRead(((comp.wiznet.p81&0x0f)<<6)|
  689.                         ((port&0x3f00)>>8));
  690.                
  691.         }
  692.                 if(port==0x83ab){
  693.                         return comp.wiznet.p83;
  694.                 }else if(port==0x82ab){
  695.                         return comp.wiznet.p82;
  696.                 }else if(port==0x81ab){
  697.                         return comp.wiznet.p81;
  698.                 }else if(port&0x8000){return 0xFF;}
  699.  
  700.                 return 0xff;
  701. }
  702.  
  703.