Subversion Repositories pentevo

Rev

Rev 1134 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
819 DimkaM 1
#include "std.h"
2
#include "emul.h"
3
#include "vars.h"
4
#include "zxusbnet.h"
885 lvd 5
#include <iphlpapi.h>
819 DimkaM 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
830 dimkam 116
        u_char PROTOR;
847 DimkaM 117
        u_char BINDED;
819 DimkaM 118
}soc[8];
847 DimkaM 119
//static char myIP[4];
819 DimkaM 120
static sockaddr_in sa_in;
847 DimkaM 121
static sockaddr_in r_sa_in;
122
//static u_long len_test;
819 DimkaM 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;
847 DimkaM 128
//static char * s_ptr;
819 DimkaM 129
static fd_set fd_s;
847 DimkaM 130
//static fd_set fd_s1;
819 DimkaM 131
static u_long is_blocked = 0, non_blocked = 1;
132
WSADATA wsaData;
133
 
847 DimkaM 134
void soc_bind(sInfoStruct * s){
135
        ZeroMemory(&sa_in, sizeof(sa_in));
136
        sa_in.sin_family = AF_INET;
884 DimkaM 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);;
847 DimkaM 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
 
819 DimkaM 146
void WizRecv(sInfoStruct * s){
147
        if (s->rx_ptr)return;
148
        int len=0;
830 dimkam 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:
847 DimkaM 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);
830 dimkam 158
                        break; 
159
                case Sn_MR_IPRAW:
847 DimkaM 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);
830 dimkam 165
                        break; 
819 DimkaM 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;
830 dimkam 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:
847 DimkaM 187
                        *((ULONG*)s->rx) = r_sa_in.sin_addr.S_un.S_addr;
188
                        *((u_short*)&s->rx[4]) = r_sa_in.sin_port;
830 dimkam 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:
847 DimkaM 194
                        *((ULONG*)s->rx) = r_sa_in.sin_addr.S_un.S_addr;
830 dimkam 195
                        s->rx[4] = (len & 0xff00) >> 8;
196
                        s->rx[5] = len & 0x00ff;
197
                        s->RX_RSR = (len + 7) & 0x0001fffe;
198
                        break; 
819 DimkaM 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);
1136 dimkam 220
 
221
        if (iResult == SOCKET_ERROR) return SOCK_CLOSED;
222
 
223
        if (s->tcpState == TCP_STATE::LISTEN)
224
        {
819 DimkaM 225
                s->list = accept(s->s, (sockaddr *)&s->sa_in, &ns);
1136 dimkam 226
                if ( s->list != INVALID_SOCKET )
227
                {
819 DimkaM 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
        }
1136 dimkam 239
 
819 DimkaM 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;
830 dimkam 266
                case Sn_MR_IPRAW:
267
                        return SOCK_IPRAW;
819 DimkaM 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;
830 dimkam 299
                case Sn_MR_IPRAW:
300
                        return SOCK_IPRAW;
819 DimkaM 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
 
830 dimkam 336
READ_REG_FUNC(read_PROTOR){
337
        if (!z)
338
                return 0x00;
339
        else
340
                return s->PROTOR;
341
}
342
 
819 DimkaM 343
READ_REG_FUNC(read_TX_FSR32){
344
        if (z == 0) return 0;
1136 dimkam 345
        return ((sizeof(s->tx) - (s->tx_ptr - s->tx)) & 0x00010000) >> 16;
819 DimkaM 346
}
347
 
348
READ_REG_FUNC(read_TX_FSR10){
1136 dimkam 349
        if (z == 0) return ((sizeof(s->tx) - (s->tx_ptr - s->tx)) & 0x0000ff00) >> 8;
1013 lvd 350
        return (sizeof(s->tx) - ((u_int)(s->tx_ptr - s->tx))) & 0x000000fF;
819 DimkaM 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,
830 dimkam 381
        read_ZERO, read_DPORTR, read_DIPR12, read_DIPR34, read_ZERO, read_PROTOR, read_ZERO, read_ZERO,
819 DimkaM 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
};
847 DimkaM 385
void WIZ_CLOSE_SOC(sInfoStruct * s){
819 DimkaM 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;
830 dimkam 391
                s->PROTOR = 0x00;
819 DimkaM 392
        }
393
}
394
 
395
void WizOpenSocket(sInfoStruct * s){
396
        bool bOptVal = true;
847 DimkaM 397
        DWORD tout = 3000;
819 DimkaM 398
        if (s->s != INVALID_SOCKET) return;
399
        s->RX_RSR = 0;
847 DimkaM 400
        memset(&s->sa_in.sin_addr,0x00,sizeof(s->sa_in.sin_addr));
819 DimkaM 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;
847 DimkaM 405
        s->BINDED = 0;
819 DimkaM 406
        switch (s->MR[1])
407
        {
408
        case Sn_MR_TCP:
409
                s->s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
847 DimkaM 410
                setsockopt(s->s, SOL_SOCKET, SO_KEEPALIVE, (char*)&bOptVal, sizeof(bOptVal));
819 DimkaM 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;
830 dimkam 416
        case Sn_MR_IPRAW:
847 DimkaM 417
                setsockopt(s->s, SOL_SOCKET, SO_RCVTIMEO, (char*)&tout, sizeof(tout));
830 dimkam 418
                s->s = socket(AF_INET, SOCK_RAW, s->PROTOR);
419
                break;
819 DimkaM 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));
847 DimkaM 450
        s->BINDED = 1;
819 DimkaM 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
        }
830 dimkam 464
        else if ((s->MR[1] == Sn_MR_UDP) || (s->MR[1] == Sn_MR_IPRAW)){
847 DimkaM 465
                if(s->BINDED == 0) soc_bind(s);
819 DimkaM 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
 
830 dimkam 536
WRITE_REG_FUNC(write_PROTOR){
847 DimkaM 537
        if (z)s->PROTOR = d;
830 dimkam 538
}
539
 
819 DimkaM 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,
830 dimkam 558
        write_ZERO, write_DPORTR, write_DIPR12, write_DIPR34, write_ZERO, write_PROTOR, write_ZERO, write_ZERO,
819 DimkaM 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;
830 dimkam 644
                soc[i].PROTOR = 0x00;
819 DimkaM 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