Index: peripherals/spectranet.c
===================================================================
--- peripherals/spectranet.c (revision 4510)
+++ peripherals/spectranet.c (working copy)
@@ -410,6 +410,22 @@
return 0;
}
+libspectrum_error
+spectranet_end( void )
+{
+ if( w5100 ) {
+ nic_w5100_free( w5100 );
+ w5100 = NULL;
+ }
+
+ if( flash_rom ) {
+ flash_am29f010_free( flash_rom );
+ flash_rom = NULL;
+ }
+
+ return LIBSPECTRUM_ERROR_NONE;
+}
+
static libspectrum_word
get_w5100_register( memory_page *page, libspectrum_word address )
{
Index: peripherals/spectranet.h
===================================================================
--- peripherals/spectranet.h (revision 4510)
+++ peripherals/spectranet.h (working copy)
@@ -27,6 +27,7 @@
#define FUSE_SPECTRANET_H
int spectranet_init( void );
+libspectrum_error spectranet_end( void );
void spectranet_page( int via_io );
void spectranet_unpage( void );
Index: peripherals/nic/w5100_internals.h
===================================================================
--- peripherals/nic/w5100_internals.h (revision 4510)
+++ peripherals/nic/w5100_internals.h (working copy)
@@ -29,6 +29,26 @@
#ifndef FUSE_W5100_INTERNALS_H
#define FUSE_W5100_INTERNALS_H
+#ifdef WIN32
+#include <signal.h>
+#endif /* #ifdef WIN32 */
+
+#ifdef WIN32
+
+#define close_socket( x ) closesocket( x )
+#define socket_error WSAGetLastError()
+#define POLLING_INTERVAL 100000
+typedef SOCKET socket_t;
+
+#else
+
+#define INVALID_SOCKET -1
+#define close_socket( x ) close( x )
+#define socket_error errno
+typedef int socket_t;
+
+#endif /* #ifdef WIN32 */
+
typedef enum w5100_socket_mode {
W5100_SOCKET_MODE_CLOSED = 0x00,
W5100_SOCKET_MODE_TCP,
@@ -106,7 +126,7 @@
/* Host properties */
- int fd; /* Socket file descriptor */
+ socket_t fd; /* Socket file descriptor */
int socket_bound; /* True once we've bound the socket to a port */
int write_pending; /* True if we're waiting to write data on this socket */
Index: peripherals/nic/w5100_socket.c
===================================================================
--- peripherals/nic/w5100_socket.c (revision 4510)
+++ peripherals/nic/w5100_socket.c (working copy)
@@ -28,15 +28,20 @@
#include "config.h"
-#include <arpa/inet.h>
#include <errno.h>
-#include <netinet/in.h>
#include <pthread.h>
#include <string.h>
-#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#endif /* #ifdef WIN32 */
+
#include "fuse.h"
#include "ui/ui.h"
#include "w5100.h"
@@ -55,7 +60,7 @@
nic_w5100_socket_init( nic_w5100_socket_t *socket, int which )
{
socket->id = which;
- socket->fd = -1;
+ socket->fd = INVALID_SOCKET;
socket->socket_bound = 0;
socket->ok_for_io = 0;
pthread_mutex_init( &socket->lock, NULL );
@@ -113,10 +118,10 @@
void
nic_w5100_socket_free( nic_w5100_socket_t *socket )
{
- if( socket->fd != -1 ) {
+ if( socket->fd != INVALID_SOCKET ) {
w5100_socket_acquire_lock( socket );
- close( socket->fd );
- socket->fd = -1;
+ close_socket( socket->fd );
+ socket->fd = INVALID_SOCKET;
socket->socket_bound = 0;
socket->ok_for_io = 0;
socket->write_pending = 0;
@@ -171,8 +176,8 @@
w5100_socket_acquire_lock( socket_obj );
socket_obj->fd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
- if( socket_obj->fd == -1 ) {
- printf("w5100: failed to open UDP socket for socket %d; errno = %d : %s\n", socket_obj->id, errno, strerror(errno));
+ if( socket_obj->fd == INVALID_SOCKET ) {
+ printf("w5100: failed to open UDP socket for socket %d; errno = %d : %s\n", socket_obj->id, socket_error, strerror(socket_error));
w5100_socket_release_lock( socket_obj );
return;
}
@@ -187,8 +192,8 @@
w5100_socket_acquire_lock( socket_obj );
socket_obj->fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
- if( socket_obj->fd == -1 ) {
- printf("w5100: failed to open TCP socket for socket %d; errno = %d : %s\n", socket_obj->id, errno, strerror(errno));
+ if( socket_obj->fd == INVALID_SOCKET ) {
+ printf("w5100: failed to open TCP socket for socket %d; errno = %d : %s\n", socket_obj->id, socket_error, strerror(socket_error));
w5100_socket_release_lock( socket_obj );
return;
}
@@ -211,8 +216,7 @@
printf("w5100: attempting to bind socket IP %s\n", inet_ntoa(sa.sin_addr));
if( bind( socket->fd, (struct sockaddr*)&sa, sizeof(sa) ) == -1 ) {
- printf("w5100: failed to bind socket %d; errno = %d : %s\n", socket->id, errno, strerror(errno));
- w5100_socket_release_lock( socket );
+ printf("w5100: failed to bind socket %d; errno = %d : %s\n", socket->id, socket_error, strerror(socket_error));
return;
}
@@ -236,7 +240,7 @@
memcpy( &sa.sin_addr.s_addr, socket->dip, 4 );
if( connect( socket->fd, (struct sockaddr*)&sa, sizeof(sa) ) == -1 ) {
- printf("w5100: failed to connect socket %d to 0x%08x:0x%04x; errno = %d : %s\n", socket->id, ntohl(sa.sin_addr.s_addr), ntohs(sa.sin_port), errno, strerror(errno));
+ printf("w5100: failed to connect socket %d to 0x%08x:0x%04x; errno = %d : %s\n", socket->id, ntohl(sa.sin_addr.s_addr), ntohs(sa.sin_port), socket_error, strerror(socket_error));
socket->ir |= 1 << 3;
socket->state = W5100_SOCKET_STATE_CLOSED;
w5100_socket_release_lock( socket );
@@ -268,9 +272,9 @@
w5100_socket_close( nic_w5100_t *self, nic_w5100_socket_t *socket )
{
w5100_socket_acquire_lock( socket );
- if( socket->fd != -1 ) {
- close( socket->fd );
- socket->fd = -1;
+ if( socket->fd != INVALID_SOCKET ) {
+ close_socket( socket->fd );
+ socket->fd = INVALID_SOCKET;
socket->socket_bound = 0;
socket->ok_for_io = 0;
socket->state = W5100_SOCKET_STATE_CLOSED;
@@ -403,6 +407,7 @@
printf("w5100: reading 0x%02x from unsupported register 0x%03x\n", b, reg );
break;
}
+
return b;
}
@@ -481,7 +486,7 @@
{
w5100_socket_acquire_lock( socket );
- if( socket->fd != -1 ) {
+ if( socket->fd != INVALID_SOCKET ) {
/* We can process a UDP read if we're in a UDP state and there are at least
9 bytes free in our buffer (8 byte UDP header and 1 byte of actual
data). */
@@ -528,11 +533,11 @@
sa.sin_family = AF_INET;
memcpy( &sa.sin_port, socket->port, 2 );
sa.sin_addr.s_addr = htonl(INADDR_ANY);
- bytes_read = recvfrom( socket->fd, buffer + 8, bytes_free - 8, 0, (struct sockaddr*)&sa, &sa_length );
+ bytes_read = recvfrom( socket->fd, (char *)buffer + 8, bytes_free - 8, 0, (struct sockaddr*)&sa, &sa_length );
printf("w5100: read 0x%03x bytes from UDP socket %d\n", (int)bytes_read, socket->id);
}
else {
- bytes_read = recv( socket->fd, buffer, bytes_free, 0 );
+ bytes_read = recv( socket->fd, (char *)buffer, bytes_free, 0 );
printf("w5100: read 0x%03x bytes from TCP socket %d\n", (int)bytes_read, socket->id);
}
@@ -562,7 +567,7 @@
}
}
else {
- printf("w5100: error %d reading from socket %d : %s\n", errno, socket->id, strerror(errno));
+ printf("w5100: error %d reading from socket %d : %s\n", socket_error, socket->id, strerror(socket_error));
}
}
@@ -592,7 +597,7 @@
memcpy( &sa.sin_port, socket->dport, 2 );
memcpy( &sa.sin_addr.s_addr, socket->dip, 4 );
- bytes_sent = sendto( socket->fd, data, length, 0, (struct sockaddr*)&sa, sizeof(sa) );
+ bytes_sent = sendto( socket->fd, (const char *)data, length, 0, (struct sockaddr*)&sa, sizeof(sa) );
printf("w5100: sent 0x%03x bytes of 0x%03x to UDP socket %d\n", (int)bytes_sent, length, socket->id);
if( bytes_sent == length ) {
@@ -609,7 +614,7 @@
else if( bytes_sent != -1 )
printf("w5100: didn't manage to send full datagram to UDP socket %d?\n", socket->id);
else
- printf("w5100: error %d writing to UDP socket %d : %s\n", errno, socket->id, strerror(errno));
+ printf("w5100: error %d writing to UDP socket %d : %s\n", socket_error, socket->id, strerror(socket_error));
}
static void
@@ -626,7 +631,7 @@
if( offset + length > 0x800 )
length = 0x800 - offset;
- bytes_sent = send( socket->fd, data, length, 0 );
+ bytes_sent = send( socket->fd, (const char*)data, length, 0 );
printf("w5100: sent 0x%03x bytes of 0x%03x to TCP socket %d\n", (int)bytes_sent, length, socket->id);
if( bytes_sent != -1 ) {
@@ -637,7 +642,7 @@
}
}
else
- printf("w5100: error %d writing to TCP socket %d : %s\n", errno, socket->id, strerror(errno));
+ printf("w5100: error %d writing to TCP socket %d : %s\n", socket_error, socket->id, strerror(socket_error));
}
void
@@ -648,7 +653,7 @@
/* Process only if we're an open socket, and we haven't been closed and
re-opened since the select() started */
- if( socket->fd != -1 && socket->ok_for_io ) {
+ if( socket->fd != INVALID_SOCKET && socket->ok_for_io ) {
if( FD_ISSET( socket->fd, &readfds ) )
w5100_socket_process_read( socket );
Index: peripherals/nic/w5100.c
===================================================================
--- peripherals/nic/w5100.c (revision 4510)
+++ peripherals/nic/w5100.c (working copy)
@@ -29,12 +29,21 @@
#include "config.h"
#include <errno.h>
-#include <netinet/in.h>
#include <pthread.h>
-#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
+#ifdef WIN32
+
+#include <winsock2.h>
+
+#else
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+#endif /* #ifdef WIN32 */
+
#include "fuse.h"
#include "ui/ui.h"
#include "w5100.h"
@@ -92,20 +101,29 @@
{
nic_w5100_t *self = arg;
int i;
+ fd_set readfds, writefds;
+ int max_fd;
+#ifdef WIN32
+ struct timeval tv;
+ fd_set *readfds_p, *writefds_p;
+#endif /* ifdef WIN32 */
+
while( !self->stop_io_thread ) {
- fd_set readfds, writefds;
- int max_fd = self->pipe_read;
+ max_fd = -1;
+ FD_ZERO( &readfds );
+ FD_ZERO( &writefds );
- FD_ZERO( &readfds );
+#ifndef WIN32
+ max_fd = self->pipe_read;
FD_SET( self->pipe_read, &readfds );
+#endif /* ifndef WIN32 */
- FD_ZERO( &writefds );
-
for( i = 0; i < 4; i++ )
nic_w5100_socket_add_to_sets( &self->socket[i], &readfds, &writefds,
&max_fd );
+#ifndef WIN32
printf("w5100: io thread select\n");
select( max_fd + 1, &readfds, &writefds, NULL, NULL );
@@ -117,7 +135,31 @@
printf("w5100: discarding pipe data\n");
read( self->pipe_read, &bitbucket, 1 );
}
+#else
+ /* Set max wait time upto 0.1 sec if not IO is completed */
+ tv.tv_sec = 0;
+ tv.tv_usec = POLLING_INTERVAL;
+ readfds_p = ( readfds.fd_count )? &readfds : NULL;
+ writefds_p = ( writefds.fd_count )? &writefds : NULL;
+
+ /* Call select() only if there are pending sockets */
+ if( readfds_p || writefds_p )
+ {
+ printf("w5100: io thread select\n");
+
+ if( select( max_fd + 1, readfds_p, writefds_p, NULL, &tv ) < 0 ) {
+ printf( "w5100: io thread wake from select with error %d\n",
+ socket_error );
+ }
+ }
+ else {
+ usleep( tv.tv_usec );
+ }
+
+ printf("w5100: io thread wake\n");
+#endif /* ifndef WIN32 */
+
for( i = 0; i < 4; i++ )
nic_w5100_socket_process_io( &self->socket[i], readfds, writefds );
}
@@ -128,17 +170,38 @@
void
nic_w5100_wake_io_thread( nic_w5100_t *self )
{
+#ifndef WIN32
const char dummy = 0;
write( self->pipe_write, &dummy, 1 );
+#endif /* ifndef WIN32 */
}
nic_w5100_t*
nic_w5100_alloc( void )
{
int error;
- int pipefd[2];
int i;
+#ifndef WIN32
+ int pipefd[2];
+#else
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD( 2, 2 );
+ error = WSAStartup( wVersionRequested, &wsaData );
+ if( error ) {
+ ui_error( UI_ERROR_ERROR, "WSAStartup failed with error: %d", error );
+ fuse_abort();
+ }
+ printf("WSAStartup\n");
+ if( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) {
+ WSACleanup();
+ ui_error( UI_ERROR_ERROR, "FUSE could not find an usable Winsock DLL" );
+ fuse_abort();
+ }
+#endif /* ifndef WIN32 */
+
nic_w5100_t *self = malloc( sizeof( *self ) );
if( !self ) {
ui_error( UI_ERROR_ERROR, "%s:%d out of memory", __FILE__, __LINE__ );
@@ -150,6 +213,7 @@
w5100_reset( self );
+#ifndef WIN32
error = pipe( pipefd );
if( error ) {
ui_error( UI_ERROR_ERROR, "w5100: error %d creating pipe", error );
@@ -158,6 +222,7 @@
self->pipe_read = pipefd[0];
self->pipe_write = pipefd[1];
+#endif /* ifndef WIN32 */
self->stop_io_thread = 0;
@@ -178,11 +243,22 @@
self->stop_io_thread = 1;
nic_w5100_wake_io_thread( self );
+#ifdef WIN32
+ /* wait IO thread wake up */
+ usleep( 2 * POLLING_INTERVAL );
+#endif /* ifdef WIN32 */
+
pthread_join( self->thread, NULL );
for( i = 0; i < 4; i++ )
nic_w5100_socket_free( &self->socket[i] );
-
+
+#ifdef WIN32
+ printf("WSACleanup\n");
+ if( WSACleanup() )
+ printf( "Error in WSACleanup: %d\n", socket_error );
+#endif /* ifdef WIN32 */
+
free( self );
}
Index: fuse.c
===================================================================
--- fuse.c (revision 4510)
+++ fuse.c (working copy)
@@ -831,6 +831,7 @@
opus_end();
plusd_end();
disciple_end();
+ spectranet_end();
machine_end();
Index: configure.in
===================================================================
--- configure.in (revision 4510)
+++ configure.in (working copy)
@@ -110,7 +110,7 @@
AC_MSG_RESULT($win32)
if test "$win32" = yes; then
AC_CHECK_HEADER(windows.h,
- LIBS="$LIBS -mwindows -lcomctl32 -lwinmm";
+ LIBS="$LIBS -mwindows -lcomctl32 -lwinmm -lpthread";
AC_DEFINE([UI_WIN32], 1, [Defined if Win32 UI in use])
AC_DEFINE([WINVER], 0x0400, [Minimal supported version of Windows is 95 or NT4])
AC_DEFINE([_WIN32_IE], 0x400, [Internet Explorer is 4.0 or higher is required])