diff -Naur brickos-0.2.6.10.6_unpatched/h8300.rcx brickos-0.2.6.10.6_patched/h8300.rcx
--- brickos-0.2.6.10.6_unpatched/h8300.rcx	2003-02-16 21:43:49.000000000 +0100
+++ brickos-0.2.6.10.6_patched/h8300.rcx	2004-09-28 10:39:55.000000000 +0200
@@ -16,7 +16,7 @@
   ram      : o = 0x8000, l = 0x6f30
   lcddata  : o = 0xef30, l = 0x0020   /* display memory */
   ram2     : o = 0xef50, l = 0x00b0
-  ram3     : o = 0xf002, l = 0x0b7e
+  ram3     : o = 0xf000, l = 0x0b80
   romdata  : o = 0xfd80, l = 0x0040   /* port shadows, interrupt vectors */
   ram4     : o = 0xfe00, l = 0x0100
 
@@ -49,7 +49,7 @@
     
   .text :	{
     ___text = . ;
-    *(.text) 	      /* must start with text for clean entry */			
+    *(.text) 	      /* must start with text for clean entry */
     *(.rodata)
     *(.strings)
     *(.vectors)       /* vectors region (dummy) */
@@ -74,7 +74,13 @@
     __edata = . ;
   } > ram
 
-  .bss : {
+  .text.hi : {
+    ___text_hi = . ;
+    *(.text.hi)
+    ___etext_hi = . ;
+  } > ram3 AT>ram
+
+  .bss ___data_end : {
     ___bss     = . ;
     _bss_start = . ; 
     *(.bss)
@@ -82,13 +88,7 @@
     ___bss_end = ALIGN(2) ;
     _mm_start  = ALIGN(2) ;    /* start memory management here */
     _end       = ALIGN(2) ;  
-  } >ram
-
-  .text.hi : AT (_bss_start) {
-    ___text_hi = . ;
-    *(.text.hi)
-    ___etext_hi = . ;
-  } > ram3
+  } AT>ram
 
   .lcddata : {
     _display_memory =  0xef43 - 0xef30 ; 
diff -Naur brickos-0.2.6.10.6_unpatched/lib/c++/stub.c brickos-0.2.6.10.6_patched/lib/c++/stub.c
--- brickos-0.2.6.10.6_unpatched/lib/c++/stub.c	2004-01-26 04:08:10.000000000 +0100
+++ brickos-0.2.6.10.6_patched/lib/c++/stub.c	2004-09-28 10:39:55.000000000 +0200
@@ -96,3 +96,9 @@
   __terminate();
 }
 
+void
+__cxa_pure_virtual()
+{
+  __terminate();
+}
+
diff -Naur brickos-0.2.6.10.6_unpatched/lib/float/addsf3.s brickos-0.2.6.10.6_patched/lib/float/addsf3.s
--- brickos-0.2.6.10.6_unpatched/lib/float/addsf3.s	2004-02-16 03:44:49.000000000 +0100
+++ brickos-0.2.6.10.6_patched/lib/float/addsf3.s	2004-09-28 10:39:55.000000000 +0200
@@ -184,7 +184,7 @@
         mov.w   @(6,r7),r1
         not.b   r2l             ; negate exponent difference
         not.b   r2h
-        adds.w  #1,r2
+        adds    #1,r2
 
     endif_2:
 
diff -Naur brickos-0.2.6.10.6_unpatched/lib/float/expandsf.s brickos-0.2.6.10.6_patched/lib/float/expandsf.s
--- brickos-0.2.6.10.6_unpatched/lib/float/expandsf.s	2004-02-16 03:45:14.000000000 +0100
+++ brickos-0.2.6.10.6_patched/lib/float/expandsf.s	2004-09-28 10:39:55.000000000 +0200
@@ -118,7 +118,7 @@
 
                 ; Decrement exponent
 
-                subs.w  #1,r4
+                subs    #1,r4
 
                 ; Is one bit set?  (one bit is in 1 << 23 or 00800000 position)
 
diff -Naur brickos-0.2.6.10.6_unpatched/lib/float/fixsfsi.s brickos-0.2.6.10.6_patched/lib/float/fixsfsi.s
--- brickos-0.2.6.10.6_unpatched/lib/float/fixsfsi.s	2004-02-16 03:46:17.000000000 +0100
+++ brickos-0.2.6.10.6_patched/lib/float/fixsfsi.s	2004-09-28 10:39:55.000000000 +0200
@@ -192,7 +192,7 @@
 
     ; Subtract bias + 31 from exponent
 
-    add.b   #-158,r4l           ; subtract bias + 31 from exponent
+    add.b   #256-158,r4l        ; subtract bias + 31 from exponent
     addx.b  #-1,r4h
 
     ; Is exponent < 0 ?
diff -Naur brickos-0.2.6.10.6_unpatched/lib/float/floatsisf.s brickos-0.2.6.10.6_patched/lib/float/floatsisf.s
--- brickos-0.2.6.10.6_unpatched/lib/float/floatsisf.s	2004-02-16 03:46:17.000000000 +0100
+++ brickos-0.2.6.10.6_patched/lib/float/floatsisf.s	2004-09-28 10:39:55.000000000 +0200
@@ -135,7 +135,7 @@
 
         ; Increase exponent
 
-        adds.w  #1,r4           ; add one to exponent
+        adds    #1,r4           ; add one to exponent
 
         bra     endif_1
 
diff -Naur brickos-0.2.6.10.6_unpatched/lib/float/joinsf.s brickos-0.2.6.10.6_patched/lib/float/joinsf.s
--- brickos-0.2.6.10.6_unpatched/lib/float/joinsf.s	2004-02-16 03:46:17.000000000 +0100
+++ brickos-0.2.6.10.6_patched/lib/float/joinsf.s	2004-09-28 10:39:55.000000000 +0200
@@ -197,7 +197,7 @@
 
         ; Increase exponent
 
-        adds.w  #1,r4           ; add one to exponent
+        adds    #1,r4           ; add one to exponent
 
     endif_5:
 
diff -Naur brickos-0.2.6.10.6_unpatched/lib/float/normalsf.s brickos-0.2.6.10.6_patched/lib/float/normalsf.s
--- brickos-0.2.6.10.6_unpatched/lib/float/normalsf.s	2004-02-16 03:47:58.000000000 +0100
+++ brickos-0.2.6.10.6_patched/lib/float/normalsf.s	2004-09-28 10:39:55.000000000 +0200
@@ -51,7 +51,7 @@
 
         ; Decrement exponent
 
-        subs.w  #1,r4
+        subs    #1,r4
 
         ; Repeat
 
diff -Naur brickos-0.2.6.10.6_unpatched/util/dll-src/genlds.c brickos-0.2.6.10.6_patched/util/dll-src/genlds.c
--- brickos-0.2.6.10.6_unpatched/util/dll-src/genlds.c	2004-01-03 20:57:46.000000000 +0100
+++ brickos-0.2.6.10.6_patched/util/dll-src/genlds.c	2004-09-28 10:39:55.000000000 +0200
@@ -192,7 +192,7 @@
   .stack : {\n\
     _stack = . ; \n\
     *(.stack)\n\
-  }  > topram\n\
+  }  > stack\n\
 \n\
   .eight 0xff00: {\n\
     *(.eight)\n\
diff -Naur brickos-0.2.6.10.6_unpatched/util/dll-src/loader.c brickos-0.2.6.10.6_patched/util/dll-src/loader.c
--- brickos-0.2.6.10.6_unpatched/util/dll-src/loader.c	2003-02-14 06:30:40.000000000 +0100
+++ brickos-0.2.6.10.6_patched/util/dll-src/loader.c	2004-09-28 10:41:38.000000000 +0200
@@ -175,6 +175,9 @@
 
   // transmit
   //
+#if defined(LINUX) || defined(linux)
+   if (tty_usb == 0)
+#endif
   keepaliveRenew();
 
   return mywrite(rcxFD(), data, length)!=length;
@@ -306,6 +309,11 @@
     myperror("opening tty");
     exit(1);
   }
+
+#if defined(LINUX) || defined(linux)
+  if (tty_usb == 0) {
+#endif
+     
   keepaliveInit();
    
   // wait for IR to settle
@@ -318,9 +326,15 @@
          	  now.tv_usec - timeout.tv_usec;
       
   } while(diff < 100000);
+#if defined(LINUX) || defined(linux)
+  }
+#endif
 #if defined(_WIN32)
   PurgeComm(rcxFD(), PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
 #else
+#if defined(LINUX) || defined(linux)
+   if (tty_usb == 0)
+#endif
   read(rcxFD(),buffer,256);
 #endif
 }
@@ -438,6 +452,8 @@
 	"  -t<comport>  , --tty=<comport>       set IR Tower com port <comport>\n"
 #if defined(_WIN32)
 	"  -t<usb>      , --tty=<usb>           set IR Tower USB mode \n"
+#else
+        "                                       (if \"usb\" is in the port, use USB mode)\n"
 #endif
 	"  -i<0/1>      , --irmode=<0/1>        set IR mode near(0)/far(1) on RCX\n"
 	"  -e           , --execute             execute program after download\n"
@@ -480,6 +496,16 @@
 		fputs("\n\n Hary Mahesan - LEGO USB IR Tower Mode\n\n",stderr);
 	tty="\\\\.\\legotower1"; // Set the correct usb tower if you have more than one (unlikely).
   }
+#elif defined(LINUX) || defined(linux)
+   /* If the tty string contains "usb", e.g. /dev/usb/lego0, we */
+   /* assume it is the USB tower.  /dev/usb/lego0 is the default name of */
+   /* the device in the LegoUSB (http://legousb.sourceforge.net) project. */
+   /* If yours doesn't contain the "usb" string, just link it. */
+   if (strstr(tty,"usb") !=0) {
+       tty_usb=1;
+       if (verbose_flag)
+          fputs("\nC.P. Chan & Tyler Akins - USB IR Tower Mode for Linux.\n",stderr);
+   }
 #endif
 
   LNPinit(tty);
diff -Naur brickos-0.2.6.10.6_unpatched/util/dll-src/rcxtty.c brickos-0.2.6.10.6_patched/util/dll-src/rcxtty.c
--- brickos-0.2.6.10.6_unpatched/util/dll-src/rcxtty.c	2002-08-20 05:04:29.000000000 +0200
+++ brickos-0.2.6.10.6_patched/util/dll-src/rcxtty.c	2004-09-28 10:41:38.000000000 +0200
@@ -47,6 +47,7 @@
 #else
   #include <termios.h>
   #include <string.h>
+  #include <errno.h>
 #endif
 
 #include "rcxtty.h"
@@ -77,7 +78,31 @@
     else
       return -1;
 #else
-    return write(fd, buf, len);
+   /* For usb tower, the driver, legousbtower, uses interrupt  */
+   /* urb which can only carry up to 8 bytes at a time. To     */
+   /* transmit more we have to check and send the rest.  It is */
+   /* a good thing to check, so I'll make it general.          */
+   
+   int actual = 0;
+   int rc;
+   char * cptr;
+   int retry = 1000;
+   
+   if (len < 1) return len;
+   cptr = (char *) buf;
+   while (actual < len) {
+      rc = (long) write(fd, cptr+actual, len-actual);
+      if (rc == -1) {
+	 if ((errno == EINTR) || (errno == EAGAIN))  {
+	    rc = 0;
+	    usleep(10);
+	    retry --;
+	 } else return -1;
+      }
+      actual += rc;
+      if (retry < 1) return actual;
+   }
+   return len;
 #endif
 }
 
@@ -124,7 +149,7 @@
   }
 
 #if !defined(_WIN32)
-  if (!isatty(fd)) {
+  if (tty_usb == 0 && !isatty(fd)) {
     close(fd);
     fprintf(stderr, "%s: not a tty\n", tty);
     return -1;
@@ -172,6 +197,7 @@
   }
   rcxFd=fd;
 #else
+  if (tty_usb == 0) {
   memset(&ios, 0, sizeof(ios));
   ios.c_cflag = CREAD | CLOCAL | CS8 | (highspeed ? 0 : PARENB | PARODD);
 
@@ -181,6 +207,7 @@
   if (tcsetattr(fd, TCSANOW, &ios) == -1) {
     perror("tcsetattr");
     exit(1);
+     }
   }
   rcxFd=fd;
 #endif
diff -Naur brickos-0.2.6.10.6_unpatched/util/firmdl/firmdl.c brickos-0.2.6.10.6_patched/util/firmdl/firmdl.c
--- brickos-0.2.6.10.6_unpatched/util/firmdl/firmdl.c	2002-10-12 05:22:26.000000000 +0200
+++ brickos-0.2.6.10.6_patched/util/firmdl/firmdl.c	2004-09-28 10:41:38.000000000 +0200
@@ -389,6 +389,8 @@
 	    "      --tty=TTY    assume tower connected to TTY\n"
 #if defined(_WIN32)
 	    "      --tty=usb    assume tower connected to USB\n"
+#else
+	    "                   (if device name contains \"usb\", use USB mode\n"
 #endif
 	    "  -h, --help       display this help and exit\n"
 	    ;
@@ -417,6 +419,17 @@
 		fprintf(stderr, "Hary Mahesan - USB IR Tower Mode.\n");
 	tty = "\\\\.\\legotower1"; // Set the correct usb tower if you have more than one (unlikely).
     }
+#elif defined(LINUX) || defined(linux)
+    /* If the tty string contains "usb", e.g. /dev/usb/lego0, we */
+    /* assume it is the USB tower.  If you use something else that doesn't */
+    /* have "usb" in the device name, link it.  /dev/usb/lego0 is the */
+    /* name of the dirver installed by LegoUSB */
+    /* (http://legousb.sourceforge.net) */
+    if (strstr(tty,"usb") !=0) {
+       tty_usb=1;
+       if (__comm_debug)
+	 fprintf(stderr, "P.C. Chan & Tyler Akins - USB IR Tower Mode for Linux.\n");
+    }   
 #endif
 
     if (use_fast && (tty_usb==0)) { //For now, run USB only at 2400bps (slow mode).
diff -Naur brickos-0.2.6.10.6_unpatched/util/firmdl/legousbtower.h brickos-0.2.6.10.6_patched/util/firmdl/legousbtower.h
--- brickos-0.2.6.10.6_unpatched/util/firmdl/legousbtower.h	1970-01-01 01:00:00.000000000 +0100
+++ brickos-0.2.6.10.6_patched/util/firmdl/legousbtower.h	2004-09-28 11:23:03.000000000 +0200
@@ -0,0 +1,52 @@
+/*
+ * legousbtower Lego USB IR Tower Linux Driver 
+ *
+ *      Copyright (c) 2001-2002 The LegoUSB DevTeam <legousb-devteam@lists.sourceforge.net>
+ * 
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License as
+ *	published by the Free Software Foundation; either version 2 of
+ *	the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef __LEGOUSBTOWER_H
+#define __LEGOUSBTOWER_H
+
+#define LEGO_TOWER_SET_PARAM _IOW('u', 0xb0, int)
+#define LEGO_TOWER_GET_PARAM _IOW('u', 0xb1, int)
+#define LEGO_TOWER_RESET _IO('u', 0xb3)
+
+
+#define LEGO_TOWER_SET_READ_TIMEOUT _IOW('u', 0xc8, int)
+#define LEGO_TOWER_SET_WRITE_TIMEOUT _IOW('u', 0xc9, int)
+
+
+#define LEGO_USB_TOWER_REQUEST_GET		1
+#define LEGO_USB_TOWER_REQUEST_SET		2
+#define LEGO_USB_TOWER_REQUEST_RESET		4 
+
+
+#define LEGO_USB_TOWER_ADDRESS_MODE		1
+#define LEGO_USB_TOWER_ADDRESS_POWER_LEVEL	2
+
+#define LEGO_USB_TOWER_POWER_LEVEL_LOW		1
+#define LEGO_USB_TOWER_POWER_LEVEL_MEDIUM	2
+#define LEGO_USB_TOWER_POWER_LEVEL_HIGH		3
+
+#define LEGO_USB_TOWER_MODE_VLL			1
+#define LEGO_USB_TOWER_MODE_RCX			2
+
+
+
+struct request_reply
+{
+	unsigned short length;
+	unsigned char  error_code;
+	unsigned char  value;
+	unsigned char  buffer[16];   // variable replies from the tower
+	                   // at this stage we aren't interested in the data
+};
+
+#endif
diff -Naur brickos-0.2.6.10.6_unpatched/util/firmdl/rcx_comm.c brickos-0.2.6.10.6_patched/util/firmdl/rcx_comm.c
--- brickos-0.2.6.10.6_unpatched/util/firmdl/rcx_comm.c	2002-08-29 05:52:50.000000000 +0200
+++ brickos-0.2.6.10.6_patched/util/firmdl/rcx_comm.c	2004-09-28 11:22:28.000000000 +0200
@@ -49,6 +49,18 @@
 
 #if defined(_WIN32)
   #include <windows.h>
+#else
+
+  /*
+   * Include the constants for usb tower form the LEGOUSB Project. 
+   * The file legousbtower.h contains all this stuff.
+   * Matthias Ehmann, Universitaet Bayreuth, matthias.ehmann@uni-bayreuth.de 
+   */
+  #include "legousbtower.h"
+  // This line is not needed any more
+  // #include <LegoUSB/driver.h>   
+  #include <sys/ioctl.h>
+  #include <errno.h>
 #endif
 
 #include "rcx_comm.h"
@@ -99,6 +111,11 @@
 {
     char *bufp = (char *)buf;
     int len = 0;
+#if defined(LINUX) | defined(linux)
+   int count;
+   fd_set fds;
+   struct timeval tv;
+#endif
 
     while (len < maxlen) {
 
@@ -157,10 +174,16 @@
         }
 	}
 #else
-	int count;
-	fd_set fds;
-	struct timeval tv;
-
+       if (tty_usb == 1)
+	 {
+	    // LegoUSB doesn't work with select(), so just set a read
+	    // timeout and then later check to see if the read timed out
+	    // without reading data.
+
+	    ioctl(fd, LEGO_TOWER_SET_READ_TIMEOUT, timeout);
+	 }
+       else
+	 {
 	FD_ZERO(&fds);
 	FD_SET(fd, &fds);
 
@@ -171,11 +194,18 @@
 	    perror("select");
 	    exit(1);
 	}
-
 	if (!FD_ISSET(fd, &fds))
 	    break;
+	 }
+
+	count = read(fd, &bufp[len], maxlen - len);
 
-	if ((count = read(fd, &bufp[len], maxlen - len)) < 0) {
+        // If no data was read from a USB tower and the read() timed out,
+	// go ahead and assume we are done reading data.
+        if (tty_usb == 1 && count == -1 && errno == ETIMEDOUT)
+	 break;
+
+	if (count < 0) {
 	    perror("read");
 	    exit(1);
 	}
@@ -210,7 +240,31 @@
     WriteFile(fd, buf, len, &nBytesWritten, NULL);
     return nBytesWritten;
 #else
-    return write(fd, buf, len);
+   /* For usb tower, the driver, legousbtower, uses interrupt  */
+   /* urb which can only carry up to 8 bytes at a time. To     */
+   /* transmit more we have to check and send the rest.  It is */
+   /* a good thing to check, so I'll make it general.          */
+
+   int actual = 0;
+   int rc;
+   char * cptr;
+   int retry = 1000;
+
+   if (len < 1) return len;
+   cptr = (char *) buf;
+   while (actual < len) {
+     rc = (long) write(fd, cptr+actual, len-actual);
+     if (rc == -1) {
+       if ((errno == EINTR) || (errno == EAGAIN))  {
+         rc = 0;
+         usleep(10);
+         retry --;
+       } else return -1;
+     }
+     actual += rc;
+     if (retry < 1) return actual;
+   }
+   return len;
 #endif
 }
 
@@ -270,6 +324,7 @@
 	exit(1);
     }
 
+    if (tty_usb == 0){
     if (!isatty(fd)) {
 	close(fd);
 	fprintf(stderr, "%s: not a tty\n", tty);
@@ -293,6 +348,7 @@
 	perror("tcsetattr");
 	exit(1);
     }
+    }
 #endif
 
     return fd;

