Subversion Repositories pentevo

Rev

Rev 1134 | 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.        
  221.         if (iResult == SOCKET_ERROR) return SOCK_CLOSED;
  222.        
  223.         if (s->tcpState == TCP_STATE::LISTEN)
  224.         {
  225.                 s->list = accept(s->s, (sockaddr *)&s->sa_in, &ns);
  226.                 if ( s->list != INVALID_SOCKET )
  227.                 {
  228.                         ioctlsocket(s->s, FIONBIO, &is_blocked);
  229.                         closesocket(s->s);
  230.                         s->s = s->list;
  231.                         ioctlsocket(s->s, FIONBIO, &non_blocked);
  232.                         bool bOptVal = true;
  233.                         setsockopt(s->s, SOL_SOCKET, SO_KEEPALIVE, (char*)bOptVal, sizeof(bOptVal));
  234.                         s->tcpState = TCP_STATE::LISTEN_CONNECTED;
  235.                         return SOCK_ESTABLISHED;
  236.                 }
  237.                 return SOCK_LISTEN;
  238.         }
  239.        
  240.         FD_ZERO(&fd_s);
  241.         FD_SET(s->s, &fd_s);
  242.         iResult = select(0, NULL, &fd_s, NULL, &select_timeout);
  243.         if (iResult == SOCKET_ERROR)
  244.                 return SOCK_CLOSED;
  245.         if (iResult == 0){
  246.                 switch (s->MR[1])
  247.                 {
  248.                 case Sn_MR_TCP:
  249.                         switch (s->tcpState)
  250.                         {
  251.                         case TCP_STATE::LISTEN_CONNECTED:
  252.                         case TCP_STATE::CLIENT_CONNECTED:
  253.                                 return SOCK_ESTABLISHED;
  254.                         default:
  255.                                 FD_ZERO(&fd_s);
  256.                                 FD_SET(s->s, &fd_s);
  257.                                 iResult = select(0, NULL, NULL, &fd_s, &select_timeout);
  258.                                 if (iResult != 0){
  259.                                         s->tcpState = TCP_STATE::CLOSED;
  260.                                         return SOCK_CLOSED;
  261.                                 }
  262.                                 return SOCK_INIT;
  263.                         }
  264.                 case Sn_MR_UDP:
  265.                         return SOCK_UDP;
  266.                 case Sn_MR_IPRAW:
  267.                         return SOCK_IPRAW;
  268.                 default:
  269.                         return SOCK_CLOSED;
  270.                 }
  271.         }
  272.         else if (iResult > 0){
  273.                 FD_ZERO(&fd_s);
  274.                 FD_SET(s->s, &fd_s);
  275.                 iResult = select(0, NULL, NULL, &fd_s, &select_timeout);
  276.                 if (iResult != 0){
  277.                         s->tcpState = TCP_STATE::CLOSED;
  278.                         return SOCK_CLOSED;
  279.                 }
  280.                 switch (s->MR[1])
  281.                 {
  282.                 case Sn_MR_TCP:
  283.                         switch (s->tcpState)
  284.                         {
  285.                         case TCP_STATE::LISTEN:
  286.                                 s->tcpState = TCP_STATE::LISTEN_CONNECTED;
  287.                                 return SOCK_ESTABLISHED;
  288.                         case TCP_STATE::CLIENT:
  289.                                 s->tcpState = TCP_STATE::CLIENT_CONNECTED;
  290.                                 return SOCK_ESTABLISHED;
  291.                         case TCP_STATE::CLOSED:
  292.                                 return SOCK_CLOSED;
  293.                         }
  294.                         WizRecv(s);
  295.                         if (s->tcpState == TCP_STATE::CLOSED) return SOCK_CLOSED;
  296.                         return SOCK_ESTABLISHED;
  297.                 case Sn_MR_UDP:
  298.                         return SOCK_UDP;
  299.                 case Sn_MR_IPRAW:
  300.                         return SOCK_IPRAW;
  301.                 default:
  302.                         return SOCK_CLOSED;
  303.                 }
  304.         }
  305.         //ns = WSAGetLastError();
  306.         return SOCK_CLOSED;
  307. }
  308.  
  309. READ_REG_FUNC(read_PORTR){
  310.         return s->PORTR[z];
  311. }
  312.  
  313. READ_REG_FUNC(read_DPORTR){
  314.         if (z) return (s->sa_in.sin_port & 0xff00) >> 8;
  315.         else return s->sa_in.sin_port & 0x00ff;
  316. }
  317.  
  318. READ_REG_FUNC(read_ZERO){
  319.         return 0;
  320. }
  321.  
  322. READ_REG_FUNC(read_DIPR12){
  323.         if (!z)
  324.                 return s->sa_in.sin_addr.S_un.S_un_b.s_b1;
  325.         else
  326.                 return s->sa_in.sin_addr.S_un.S_un_b.s_b2;
  327. }
  328.  
  329. READ_REG_FUNC(read_DIPR34){
  330.         if (!z)
  331.                 return s->sa_in.sin_addr.S_un.S_un_b.s_b3;
  332.         else
  333.                 return s->sa_in.sin_addr.S_un.S_un_b.s_b4;
  334. }
  335.  
  336. READ_REG_FUNC(read_PROTOR){
  337.         if (!z)
  338.                 return 0x00;
  339.         else
  340.                 return s->PROTOR;
  341. }
  342.  
  343. READ_REG_FUNC(read_TX_FSR32){
  344.         if (z == 0) return 0;
  345.         return ((sizeof(s->tx) - (s->tx_ptr - s->tx)) & 0x00010000) >> 16;
  346. }
  347.  
  348. READ_REG_FUNC(read_TX_FSR10){
  349.         if (z == 0) return ((sizeof(s->tx) - (s->tx_ptr - s->tx)) & 0x0000ff00) >> 8;
  350.         return (sizeof(s->tx) - ((u_int)(s->tx_ptr - s->tx))) & 0x000000fF;
  351. }
  352.  
  353. READ_REG_FUNC(read_RX_RSR32){
  354.         if (s->s == INVALID_SOCKET)return 0;
  355.         if (z == 0) return 0;
  356.         WizRecv(s);
  357.         return (u_char)((s->RX_RSR & 0x00010000) >> 16);
  358. }
  359.  
  360. READ_REG_FUNC(read_RX_RSR10){
  361.         if (s->s == INVALID_SOCKET)return 0;
  362.         WizRecv(s);
  363.         if (z == 0) return (s->RX_RSR & 0x0000ff00) >> 8;
  364.         return s->RX_RSR & 0x000000fF;
  365. }
  366.  
  367. READ_REG_FUNC(read_RX){
  368.         if (s->RX_RSR == 0)return 0;
  369.         data = *(s->rx_ptr + z);
  370.         if (z == 0)return data;
  371.         s->RX_RSR -= 2;
  372.         if (s->RX_RSR == 0)
  373.                 s->rx_ptr = NULL;
  374.         else
  375.                 s->rx_ptr += 2;
  376.         return data;
  377. }
  378.  
  379. u_char(*regReadFunc[0x20])(sInfoStruct *, u_char) = {
  380.         read_MR, read_CR, read_ZERO, read_ZERO, read_SSR, read_PORTR, read_ZERO, read_ZERO,
  381.         read_ZERO, read_DPORTR, read_DIPR12, read_DIPR34, read_ZERO, read_PROTOR, read_ZERO, read_ZERO,
  382.         read_ZERO, read_ZERO, read_TX_FSR32, read_TX_FSR10, read_RX_RSR32, read_RX_RSR10, read_ZERO, read_ZERO,
  383.         read_RX, read_ZERO, read_ZERO, read_ZERO, read_ZERO, read_ZERO, read_ZERO, read_ZERO,
  384. };
  385. void WIZ_CLOSE_SOC(sInfoStruct * s){
  386.         if (s->s != INVALID_SOCKET){
  387.                 ioctlsocket(s->s, FIONBIO, &is_blocked);
  388.                 iResult = closesocket(s->s);
  389.                 DPRINTF("closesocket = %x", iResult);
  390.                 s->s = INVALID_SOCKET;
  391.                 s->PROTOR = 0x00;
  392.         }
  393. }
  394.  
  395. void WizOpenSocket(sInfoStruct * s){
  396.         bool bOptVal = true;
  397.         DWORD tout = 3000;
  398.         if (s->s != INVALID_SOCKET) return;
  399.         s->RX_RSR = 0;
  400.         memset(&s->sa_in.sin_addr,0x00,sizeof(s->sa_in.sin_addr));
  401.         s->sa_in.sin_family = AF_INET;
  402.         s->rx_ptr = NULL;
  403.         s->tx_ptr = s->tx;
  404.         s->tcpState = TCP_STATE::NONE;
  405.         s->BINDED = 0;
  406.         switch (s->MR[1])
  407.         {
  408.         case Sn_MR_TCP:
  409.                 s->s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  410.                 setsockopt(s->s, SOL_SOCKET, SO_KEEPALIVE, (char*)&bOptVal, sizeof(bOptVal));
  411.                 DPRINTF("Opensocket %u ", s->s);
  412.                 break;
  413.         case Sn_MR_UDP:
  414.                 s->s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  415.                 break;
  416.         case Sn_MR_IPRAW:
  417.                 setsockopt(s->s, SOL_SOCKET, SO_RCVTIMEO, (char*)&tout, sizeof(tout));
  418.                 s->s = socket(AF_INET, SOCK_RAW, s->PROTOR);
  419.                 break;
  420.         default:
  421.                 s->s = INVALID_SOCKET;
  422.                 break;
  423.         }
  424.         if (s->s != INVALID_SOCKET){
  425.                 ioctlsocket(s->s, FIONBIO, &non_blocked);
  426.                 s->CR = 0;
  427.         }
  428. }
  429.  
  430. void WizConnect(sInfoStruct *s){
  431.         if (s->MR[1] != Sn_MR_TCP || s->s == INVALID_SOCKET || s->tcpState != TCP_STATE::NONE) return;
  432.         s->CR = 0;
  433.         s->tcpState = TCP_STATE::CLIENT;
  434.         connect(s->s, (SOCKADDR *)&s->sa_in, sizeof(s->sa_in));
  435. }
  436.  
  437. void WisDisconnect(sInfoStruct *s){
  438.         if (s->MR[1] != Sn_MR_TCP) return;
  439. }
  440.  
  441. void WisListen(sInfoStruct *s){
  442.         if (s->MR[1] != Sn_MR_TCP || s->s == INVALID_SOCKET || s->tcpState != TCP_STATE::NONE) return;
  443.         s->tcpState = TCP_STATE::LISTEN;
  444.         ZeroMemory(&sa_in, sizeof(sa_in));
  445.         //s->list = s->s;
  446.         sa_in.sin_family = AF_INET;
  447.         sa_in.sin_addr.S_un.S_addr = 0;
  448.         sa_in.sin_port = (s->PORTR[1] << 8) | s->PORTR[0];
  449.         bind(s->s, (sockaddr *)&sa_in, sizeof(sa_in));
  450.         s->BINDED = 1;
  451.         listen(s->s, 1);
  452.         ns = sizeof(s->sa_in);
  453. }
  454.  
  455. void WizSend(sInfoStruct *s){
  456.         if (s->s == INVALID_SOCKET)return;
  457.         iResult = (int)(s->TX_WRSR.ul & 0x01ffff);
  458.         if (s->MR[1] == Sn_MR_TCP && s->tcpState != TCP_STATE::NONE){
  459.                 send(s->s, (char*)s->tx, (int)(s->TX_WRSR.ul & 0x01ffff), 0);
  460.                 s->tx_ptr = s->tx;
  461.                 s->TX_WRSR.ul = 0;
  462.                 DPRINTF("Send %d bytes\r\n", iResult);
  463.         }
  464.         else if ((s->MR[1] == Sn_MR_UDP) || (s->MR[1] == Sn_MR_IPRAW)){
  465.                 if(s->BINDED == 0) soc_bind(s);
  466.                 sendto(s->s, (char*)s->tx, (int)(s->TX_WRSR.ul & 0x01ffff), 0, (sockaddr *)&s->sa_in, sizeof(sa_in));
  467.                 s->tx_ptr = s->tx;
  468.                 s->TX_WRSR.ul = 0;
  469.                 DPRINTF("Send %d bytes\r\n", iResult);
  470.         }
  471. }
  472.  
  473. WRITE_REG_FUNC(write_DPORTR){
  474.         if (z) s->sa_in.sin_port = ((s->sa_in.sin_port) & 0x00ff) | (d << 8);
  475.         else s->sa_in.sin_port = ((s->sa_in.sin_port) & 0xff00) | d;
  476. };
  477.  
  478. WRITE_REG_FUNC(write_MR){
  479.         WIZ_CLOSE_SOC(s);
  480.         s->MR[z] = d;
  481. };
  482.  
  483. WRITE_REG_FUNC(write_CR){
  484.         if (!z)return;
  485.         DPRINTF("Write CR = %x\r\n", d);
  486.         s->CR = d;
  487.         switch (d)
  488.         {
  489.         case Sn_CR_CLOSE:
  490.                 WIZ_CLOSE_SOC(s);
  491.                 s->CR = 0;
  492.                 break;
  493.         case Sn_CR_RECV:
  494.                 s->rx_ptr = NULL;
  495.                 s->RX_RSR = 0;
  496.                 s->CR = 0;
  497.                 break;
  498.         case Sn_CR_SEND:
  499.                 WizSend(s);
  500.                 break;
  501.         case Sn_CR_DISCON:
  502.                 if (s->s != INVALID_SOCKET){
  503.                         WIZ_CLOSE_SOC(s);
  504.                         //WizOpenSocket(s);
  505.                         s->CR = 0;
  506.                 }
  507.                 break;
  508.         case Sn_CR_OPEN:
  509.                 WizOpenSocket(s);
  510.                 break;
  511.         case Sn_CR_LISTEN:
  512.                 WisListen(s);
  513.                 break;
  514.         case Sn_CR_CONNECT:
  515.                 WizConnect(s);
  516.                 break;
  517.         default:
  518.                 break;
  519.         }
  520. };
  521.  
  522. WRITE_REG_FUNC(write_PORTR){
  523.         s->PORTR[z] = d;
  524. };
  525.  
  526. WRITE_REG_FUNC(write_DIPR12){
  527.         if (!z)s->sa_in.sin_addr.S_un.S_un_b.s_b1 = d;
  528.         else s->sa_in.sin_addr.S_un.S_un_b.s_b2 = d;
  529. }
  530.  
  531. WRITE_REG_FUNC(write_DIPR34){
  532.         if (!z)s->sa_in.sin_addr.S_un.S_un_b.s_b3 = d;
  533.         else s->sa_in.sin_addr.S_un.S_un_b.s_b4 = d;
  534. }
  535.  
  536. WRITE_REG_FUNC(write_PROTOR){
  537.         if (z)s->PROTOR = d;
  538. }
  539.  
  540. WRITE_REG_FUNC(write_TX_WRSR32){
  541.         s->TX_WRSR.b[3 - z] = d;
  542. };
  543.  
  544. WRITE_REG_FUNC(write_TX_WRSR10){
  545.         s->TX_WRSR.b[1 - z] = d;
  546. };
  547.  
  548. WRITE_REG_FUNC(write_TX){
  549.         *(s->tx_ptr + z) = d;
  550.         if (z == 0)return;
  551.         s->tx_ptr += 2;
  552. };
  553.  
  554. WRITE_REG_FUNC(write_ZERO){};
  555.  
  556. void(*regWriteFunc[0x20])(sInfoStruct * s, u_char, u_char) = {
  557.         write_MR, write_CR, write_ZERO, write_ZERO, write_ZERO, write_PORTR, write_ZERO, write_ZERO,
  558.         write_ZERO, write_DPORTR, write_DIPR12, write_DIPR34, write_ZERO, write_PROTOR, write_ZERO, write_ZERO,
  559.         write_TX_WRSR32, write_TX_WRSR10, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_TX,
  560.         write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO, write_ZERO,
  561. };
  562.  
  563. u_char Wiz5300_RegRead(unsigned int Addr)
  564. {
  565.  
  566.         if(comp.wiznet.p82&0x08)Addr^=0x01;
  567.         if (Addr >= 0x0200)
  568.                 return regReadFunc[(Addr & 0x3f) >> 1](&soc[(Addr >> 6) & 0x07], Addr & 0x01);
  569.         if (Addr <= 0x00ff){
  570.                 return regs[Addr];
  571.         }
  572.         return 0;
  573. }
  574.  
  575. void Wiz5300_RegWrite(unsigned int Addr, unsigned char Data)
  576. {
  577.         if(comp.wiznet.p82&0x08)Addr^=0x01;
  578.         if (Addr >= 0x0200)
  579.                 regWriteFunc[(Addr & 0x3f) >> 1](&soc[(Addr >> 6) & 0x07], Data, Addr & 0x01);
  580.         else if (Addr <= 0x00ff) {
  581.                 regs[Addr] = stat_regs[Addr];
  582.         }
  583. }
  584.  
  585. void getNetProperties(void){
  586.         char ac[80];
  587.         gethostname(ac, sizeof(ac));
  588.         struct hostent *phe = gethostbyname(ac);
  589.         if (phe)memcpy(&stat_regs[0x0018], phe->h_addr_list[0], 4);
  590.         if (*((ULONG32*)(&stat_regs[0x0018])) == 0)return;
  591.  
  592.         PIP_ADAPTER_INFO pAdapterInfo, pAdapter = NULL;
  593.         DWORD dwRetVal = 0;
  594.         //unsigned int i;
  595.         //struct tm newtime;
  596.         //errno_t error;
  597.         ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
  598.         pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
  599.         // if (pAdapterInfo==NULL) ...return
  600.         if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW){
  601.                 free(pAdapterInfo);
  602.                 pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
  603.                 // if (pAdapterInfo==NULL) ...return
  604.         }
  605.         if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR){
  606.                 pAdapter = pAdapterInfo;
  607.                 while (pAdapter)
  608.                 {
  609.                         if (pAdapter->IpAddressList.Context != *((DWORD32*)(&stat_regs[0x0018]))){
  610.                                 pAdapter = pAdapter->Next;
  611.                                 continue;
  612.                         }
  613.                         printf("Network adapter: %s \r\n",pAdapter->Description);
  614.                         *((ULONG32*)(&stat_regs[0x0014])) = inet_addr(pAdapter->IpAddressList.IpMask.String);
  615.                         *((ULONG32*)(&stat_regs[0x0010])) = inet_addr(pAdapter->GatewayList.IpAddress.String);
  616.                         memcpy(&stat_regs[0x008], pAdapter->Address, 8);
  617.                         break;
  618.                 }
  619.         }
  620.         else
  621.         {
  622.                 //print error, no return
  623.         }
  624.         if (pAdapterInfo){
  625.                 free(pAdapterInfo);
  626.         }
  627. }
  628.  
  629. int Wiz5300_Init(void)
  630. {
  631.         ZeroMemory(stat_regs, sizeof(stat_regs));
  632.         memset(&stat_regs[0x20], 0x08, 16);
  633.         stat_regs[0x00] = 0x38;
  634.         stat_regs[0xfe] = 0x53;
  635.         stat_regs[0x31] = 0xff;
  636.         memcpy(regs, stat_regs, sizeof(stat_regs));
  637.  
  638.         ZeroMemory(soc, sizeof(soc));
  639.         WSAStartup(MAKEWORD(2, 2), &wsaData);
  640.         for (int i = 0; i < 8; i++){
  641.                 soc[i].s = INVALID_SOCKET;
  642.                 soc[i].sa_in.sin_family = AF_INET;
  643.                 soc[i].list = INVALID_SOCKET;
  644.                 soc[i].PROTOR = 0x00;
  645.         }
  646.         select_timeout.tv_sec = 0;
  647.         select_timeout.tv_usec = 0;
  648.         getNetProperties();
  649.         //DPRINTF("wiz init\r\n");
  650.         return 0;
  651. }
  652.  
  653. int Wiz5300_Close(void)
  654. {
  655.         for (int i = 0; i < 8; i++) {
  656.                 if (soc[i].s != INVALID_SOCKET){
  657.                         ioctlsocket(soc[i].s, FIONBIO, &is_blocked);
  658.                         closesocket(soc[i].s);
  659.                 }
  660.         }
  661.         WSACleanup(); //Clean up Winsock
  662.         return 0;
  663. }
  664.  
  665.  
  666. void pXXAB_Write(unsigned port, unsigned char val){
  667.         if((!(port&0x8000))&&(comp.wiznet.p82&0x10)){
  668.                 Wiz5300_RegWrite(((comp.wiznet.p81&0x0f)<<6)|
  669.                         ((port&0x3f00)>>8),val);
  670.                 return;
  671.         }
  672.         if(port==0x83ab){
  673.                 if((comp.wiznet.p83&0x10)^(val&0x10)){
  674.                         if(val&0x10){Wiz5300_Init();}
  675.                         else {Wiz5300_Close();}
  676.                 }
  677.                 comp.wiznet.p83=val;
  678.                
  679.         }else if(port==0x82ab){
  680.                 comp.wiznet.p82=val;
  681.         }else if(port==0x81ab){
  682.                 comp.wiznet.p81=val;
  683.                 return;
  684.         }
  685.         comp.wiznet.memEna=conf.wiznet && (comp.wiznet.p82 & 0x04)
  686.                 && (comp.wiznet.p83 & 0x10) && (!(comp.wiznet.p82 & 0x10));
  687.         return;
  688. }
  689.  
  690. unsigned char pXXAB_Read(unsigned port){
  691.         if((!(port&0x8000))&&(comp.wiznet.p82&0x10)){
  692.                 return Wiz5300_RegRead(((comp.wiznet.p81&0x0f)<<6)|
  693.                         ((port&0x3f00)>>8));
  694.                
  695.         }
  696.                 if(port==0x83ab){
  697.                         return comp.wiznet.p83;
  698.                 }else if(port==0x82ab){
  699.                         return comp.wiznet.p82;
  700.                 }else if(port==0x81ab){
  701.                         return comp.wiznet.p81;
  702.                 }else if(port&0x8000){return 0xFF;}
  703.  
  704.                 return 0xff;
  705. }
  706.  
  707.