Browse Source

Huge refactor of webserv, now support brfs.

Signed-off-by: bart <bart@b4rt.nl>
bart 7 months ago
parent
commit
9f23f26dc2

+ 1 - 1
BCC/BDOS/BDOS.c

@@ -145,7 +145,7 @@ void bdos_init_network()
 
   word sub_mask[4] = {255, 255, 255, 0};
 
-  wiz_Init(ip_addr, gateway_addr, mac_addr, sub_mask);
+  wiz_init(ip_addr, gateway_addr, mac_addr, sub_mask);
 }
 
 

+ 6 - 0
BCC/BDOS/lib/brfs.c

@@ -1083,6 +1083,12 @@ word brfs_write(word file_pointer, word* buffer, word length)
 */
 struct brfs_dir_entry* brfs_stat(char* file_path)
 {
+  // Remove all trailing slashes
+  while (strlen(file_path) > 1 && file_path[strlen(file_path)-1] == '/')
+  {
+    file_path[strlen(file_path)-1] = 0;
+  }
+
   // Split filename from path using basename and dirname
   char dirname_output[MAX_PATH_LENGTH];
   char* file_path_basename = basename(file_path);

+ 9 - 9
BCC/BDOS/lib/nethid.c

@@ -26,12 +26,12 @@ void NETHID_handleSession(word s)
     word rsize = 0;
     word rsizeValidate = 0;
     do {
-        rsize = wizGetSockReg16(s, WIZNET_SnRX_RSR);
+        rsize = wiz_get_sock_reg_16(s, WIZNET_SnRX_RSR);
         if (rsize != 0)
         {
             // twice on purpose
-            rsizeValidate = wizGetSockReg16(s, WIZNET_SnRX_RSR);
-            rsizeValidate = wizGetSockReg16(s, WIZNET_SnRX_RSR);
+            rsizeValidate = wiz_get_sock_reg_16(s, WIZNET_SnRX_RSR);
+            rsizeValidate = wiz_get_sock_reg_16(s, WIZNET_SnRX_RSR);
         }
     } 
     while (rsize != rsizeValidate);
@@ -43,11 +43,11 @@ void NETHID_handleSession(word s)
     }
 
     // receive data
-    wizReadRecvData(s, NETHID_rxBuf, rsize);
+    wiz_read_recv_data(s, NETHID_rxBuf, rsize);
     NETHID_rxBuf[rsize] = 0; //terminate
 
     // echo data back to confirm receive
-    wizWriteDataFromMemory(s, NETHID_rxBuf, rsize);
+    wiz_write_data(s, NETHID_rxBuf, rsize);
 
     // loop through the received data
     word isEscaped = 0;
@@ -112,7 +112,7 @@ void NETHID_handleSession(word s)
 void NETHID_init(word s)
 {
     // Open socket in TCP Server mode
-    wizInitSocketTCP(s, NETHID_PORT);
+    wiz_init_socket_tcp_host(s, NETHID_PORT);
 
     NETHID_isInitialized = 1;
 }
@@ -123,12 +123,12 @@ void NETHID_init(word s)
 void NETHID_loop(word s)
 {
     // Get status for socket s
-    word sxStatus = wizGetSockReg8(s, WIZNET_SnSR);
+    word sxStatus = wiz_get_sock_reg_8(s, WIZNET_SnSR);
 
     if (sxStatus == WIZNET_SOCK_CLOSED)
     { 
         // Open the socket when closed
-        wizInitSocketTCP(s, NETHID_PORT);
+        wiz_init_socket_tcp_host(s, NETHID_PORT);
     }
     else if (sxStatus == WIZNET_SOCK_ESTABLISHED)
     {
@@ -150,7 +150,7 @@ void NETHID_loop(word s)
         uprintlnHex(sxStatus);
         */
         // In other cases, reset the socket
-        wizInitSocketTCP(s, NETHID_PORT);
+        wiz_init_socket_tcp_host(s, NETHID_PORT);
     }
     return;
 }

+ 15 - 15
BCC/BDOS/lib/netloader.c

@@ -198,13 +198,13 @@ void NETLOADER_handleSession(word s)
     word leftOverData[4];
     word leftOverBytes = 0;
 
-    while (wizGetSockReg8(s, WIZNET_SnSR) == WIZNET_SOCK_ESTABLISHED)
+    while (wiz_get_sock_reg_8(s, WIZNET_SnSR) == WIZNET_SOCK_ESTABLISHED)
     {
-        word rsize = wizGetSockReg16(s, WIZNET_SnRX_RSR);
+        word rsize = wiz_get_sock_reg_16(s, WIZNET_SnRX_RSR);
         if (rsize != 0)
         {
             char* rbuf = (char *) TEMP_ADDR;
-            wizReadRecvData(s, rbuf, rsize);
+            wiz_read_recv_data(s, rbuf, rsize);
             if (firstResponse)
             {
                 GFX_PrintConsole("\n");
@@ -261,8 +261,8 @@ void NETLOADER_handleSession(word s)
 
                     if (failedToCreateFile)
                     {
-                        wizWriteDataFromMemory(s, "ERR!", 4);
-                        wizCmd(s, WIZNET_CR_DISCON);
+                        wiz_write_data(s, "ERR!", 4);
+                        wiz_send_cmd(s, WIZNET_CR_DISCON);
                         GFX_PrintConsole("E: Could not create file\n");
                         // clear the shell
                         shell_clear_command();
@@ -274,8 +274,8 @@ void NETLOADER_handleSession(word s)
                 else
                 {
                     // unsupported command
-                    wizWriteDataFromMemory(s, "ERR!", 4);
-                    wizCmd(s, WIZNET_CR_DISCON);
+                    wiz_write_data(s, "ERR!", 4);
+                    wiz_send_cmd(s, WIZNET_CR_DISCON);
                     GFX_PrintConsole("E: Unknown netloader cmd\n");
                     // clear the shell
                     shell_clear_command();
@@ -347,8 +347,8 @@ void NETLOADER_handleSession(word s)
                 // all data downloaded
                 if (contentLength == 0)
                 {
-                    wizWriteDataFromMemory(s, "THX!", 4);
-                    wizCmd(s, WIZNET_CR_DISCON);
+                    wiz_write_data(s, "THX!", 4);
+                    wiz_send_cmd(s, WIZNET_CR_DISCON);
 
                     if (downloadToFile)
                     {
@@ -479,8 +479,8 @@ void NETLOADER_handleSession(word s)
                 // all data downloaded
                 if (contentLength == 0)
                 {
-                    wizWriteDataFromMemory(s, "THX!", 4);
-                    wizCmd(s, WIZNET_CR_DISCON);
+                    wiz_write_data(s, "THX!", 4);
+                    wiz_send_cmd(s, WIZNET_CR_DISCON);
 
                     // remove progress prints
                     word i = strlen(dbuf);
@@ -514,7 +514,7 @@ void NETLOADER_handleSession(word s)
 void NETLOADER_init(word s)
 {
     // Open socket in TCP Server mode
-    wizInitSocketTCP(s, NETLOADER_PORT);
+    wiz_init_socket_tcp_host(s, NETLOADER_PORT);
 }
 
 
@@ -523,12 +523,12 @@ void NETLOADER_init(word s)
 word NETLOADER_loop(word s)
 {
     // Get status for socket s
-    word sxStatus = wizGetSockReg8(s, WIZNET_SnSR);
+    word sxStatus = wiz_get_sock_reg_8(s, WIZNET_SnSR);
 
     if (sxStatus == WIZNET_SOCK_CLOSED)
     { 
         // Open the socket when closed
-        wizInitSocketTCP(s, NETLOADER_PORT);
+        wiz_init_socket_tcp_host(s, NETLOADER_PORT);
     }
     else if (sxStatus == WIZNET_SOCK_ESTABLISHED)
     {
@@ -548,7 +548,7 @@ word NETLOADER_loop(word s)
     else
     {
         // In other cases, reset the socket
-        wizInitSocketTCP(s, NETLOADER_PORT);
+        wiz_init_socket_tcp_host(s, NETLOADER_PORT);
     }
 
     return 0;

+ 121 - 121
BCC/BDOS/lib/wiz5500.c

@@ -123,7 +123,7 @@ void W5500_asmDefines()
 }
 
 // Sets SPI3_CS low
-void WizSpiBeginTransfer()
+void wiz_spi_begin_transfer()
 {
     asm(
         "; backup regs\n"
@@ -142,7 +142,7 @@ void WizSpiBeginTransfer()
 }
 
 // Sets SPI3_CS high
-void WizSpiEndTransfer()
+void wiz_spi_end_transfer()
 {
     asm(
         "; backup regs\n"
@@ -163,7 +163,7 @@ void WizSpiEndTransfer()
 // write dataByte and return read value
 // write 0x00 for a read
 // Writes byte over SPI3 to W5500
-word WizSpiTransfer(word dataByte)
+word wiz_spi_transfer(word dataByte)
 {
     word retval = 0;
     asm(
@@ -178,135 +178,135 @@ word WizSpiTransfer(word dataByte)
 
 
 // Write data to W5500
-void wizWrite(word addr, word cb, char* buf, word len)
+void wiz_write(word addr, word cb, char* buf, word len)
 {
-  WizSpiBeginTransfer();
+  wiz_spi_begin_transfer();
 
   // Send address
   word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  wiz_spi_transfer(addrMSB); //msByte
+  wiz_spi_transfer(addr); //lsByte
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Send data
   word i;
   for (i = 0; i < len; i++)
   {
-    WizSpiTransfer(buf[i]);
+    wiz_spi_transfer(buf[i]);
   }
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 }
 
 
 // Write single byte to W5500
-word wizWriteSingle(word addr, word cb, word data)
+word wiz_write_single(word addr, word cb, word data)
 {
-  WizSpiBeginTransfer();
+  wiz_spi_begin_transfer();
 
   // Send address
   word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  wiz_spi_transfer(addrMSB); //msByte
+  wiz_spi_transfer(addr); //lsByte
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Send data
-  WizSpiTransfer(data);
+  wiz_spi_transfer(data);
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 
   return data;
 }
 
 
 // Write two bytes to W5500
-void wizWriteDouble(word addr, word cb, word data)
+void wiz_write_double(word addr, word cb, word data)
 {
-  WizSpiBeginTransfer();
+  wiz_spi_begin_transfer();
 
   // Send address
   word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  wiz_spi_transfer(addrMSB); //msByte
+  wiz_spi_transfer(addr); //lsByte
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Send data
   word dataMSB = (unsigned) data >> 8;
-  WizSpiTransfer(dataMSB);
-  WizSpiTransfer(data);
+  wiz_spi_transfer(dataMSB);
+  wiz_spi_transfer(data);
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 }
 
 
-void wizRead(word addr, word cb, char* buf, word len)
+void wiz_read(word addr, word cb, char* buf, word len)
 { 
-  WizSpiBeginTransfer();
+  wiz_spi_begin_transfer();
 
   // Send address
   word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  wiz_spi_transfer(addrMSB); //msByte
+  wiz_spi_transfer(addr); //lsByte
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Read data
   word i;
   for (i = 0; i < len; i++)
   {
-    buf[i] = WizSpiTransfer(0);
+    buf[i] = wiz_spi_transfer(0);
   }
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 }
 
 
-word wizReadSingle(word addr, word cb)
+word wiz_read_single(word addr, word cb)
 { 
-  WizSpiBeginTransfer();
+  wiz_spi_begin_transfer();
 
   // Send address
   word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  wiz_spi_transfer(addrMSB); //msByte
+  wiz_spi_transfer(addr); //lsByte
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Read data
-  word retval = WizSpiTransfer(0);
+  word retval = wiz_spi_transfer(0);
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 
   // Return read value
   return retval;
 }
 
 
-word wizReadDouble(word addr, word cb)
+word wiz_read_double(word addr, word cb)
 { 
-  WizSpiBeginTransfer();
+  wiz_spi_begin_transfer();
 
   // Send address
   word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  wiz_spi_transfer(addrMSB); //msByte
+  wiz_spi_transfer(addr); //lsByte
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Read data
-  word retval = WizSpiTransfer(0) << 8;
-  retval = retval + WizSpiTransfer(0);
+  word retval = wiz_spi_transfer(0) << 8;
+  retval = retval + wiz_spi_transfer(0);
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 
   // Return read value
   return retval;
@@ -318,91 +318,91 @@ word wizReadDouble(word addr, word cb)
 //-------------------
 
 // Send a command cmd to socket s
-void wizCmd(word s, word cmd)
+void wiz_send_cmd(word s, word cmd)
 {
-  //wizWriteSingle(WIZNET_SnCR, WIZNET_WRITE_SnR, cmd);
-  WizSpiBeginTransfer();
-  WizSpiTransfer(0); //msByte
-  WizSpiTransfer(WIZNET_SnCR); //lsByte
-  WizSpiTransfer(WIZNET_WRITE_SnR + (s << 5));
-  WizSpiTransfer(cmd);
-  WizSpiEndTransfer();
+  //wiz_write_single(WIZNET_SnCR, WIZNET_WRITE_SnR, cmd);
+  wiz_spi_begin_transfer();
+  wiz_spi_transfer(0); //msByte
+  wiz_spi_transfer(WIZNET_SnCR); //lsByte
+  wiz_spi_transfer(WIZNET_WRITE_SnR + (s << 5));
+  wiz_spi_transfer(cmd);
+  wiz_spi_end_transfer();
 
   // wait untill done
-  while ( wizReadSingle(WIZNET_SnCR, WIZNET_READ_SnR) );
+  while ( wiz_read_single(WIZNET_SnCR, WIZNET_READ_SnR) );
 }
 
 // Write 8 bits to a sockets control register
-void wizSetSockReg8(word s, word addr, word val)
+void wiz_set_sock_reg_8(word s, word addr, word val)
 {
-  //wizWriteSingle(addr, WIZNET_WRITE_SnR, val);
-  WizSpiBeginTransfer();
-  WizSpiTransfer(0); //msByte
-  WizSpiTransfer(addr); //lsByte
-  WizSpiTransfer(WIZNET_WRITE_SnR + (s << 5));
-  WizSpiTransfer(val);
-  WizSpiEndTransfer();
+  //wiz_write_single(addr, WIZNET_WRITE_SnR, val);
+  wiz_spi_begin_transfer();
+  wiz_spi_transfer(0); //msByte
+  wiz_spi_transfer(addr); //lsByte
+  wiz_spi_transfer(WIZNET_WRITE_SnR + (s << 5));
+  wiz_spi_transfer(val);
+  wiz_spi_end_transfer();
 }
 
 // Read 8 bits from a sockets control register
-word wizGetSockReg8(word s, word addr){
-  //return wizReadSingle(addr, WIZNET_READ_SnR);
-  WizSpiBeginTransfer();
+word wiz_get_sock_reg_8(word s, word addr){
+  //return wiz_read_single(addr, WIZNET_READ_SnR);
+  wiz_spi_begin_transfer();
 
   // Send address
   word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  wiz_spi_transfer(addrMSB); //msByte
+  wiz_spi_transfer(addr); //lsByte
 
   word cb = WIZNET_READ_SnR + (s << 5);
   
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Read data
-  word retval = WizSpiTransfer(0);
+  word retval = wiz_spi_transfer(0);
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 
   // Return read value
   return retval;
 }
 
 // Write 16 bits to a sockets control register
-void wizSetSockReg16(word s, word addr, word val)
+void wiz_set_sock_reg_16(word s, word addr, word val)
 {
-  //wizWriteDouble(addr, WIZNET_WRITE_SnR + (s << 5), val);
-  WizSpiBeginTransfer();
-  WizSpiTransfer(0); //msByte
-  WizSpiTransfer(addr); //lsByte
-  WizSpiTransfer(WIZNET_WRITE_SnR + (s << 5));
+  //wiz_write_double(addr, WIZNET_WRITE_SnR + (s << 5), val);
+  wiz_spi_begin_transfer();
+  wiz_spi_transfer(0); //msByte
+  wiz_spi_transfer(addr); //lsByte
+  wiz_spi_transfer(WIZNET_WRITE_SnR + (s << 5));
   word valMSB = (unsigned) val >> 8;
-  WizSpiTransfer(valMSB);
-  WizSpiTransfer(val);
-  WizSpiEndTransfer();
+  wiz_spi_transfer(valMSB);
+  wiz_spi_transfer(val);
+  wiz_spi_end_transfer();
 }
 
 // Read 16 bits from a sockets control register
-word wizGetSockReg16(word s, word addr)
+word wiz_get_sock_reg_16(word s, word addr)
 {
-  //return wizReadDouble(addr, WIZNET_READ_SnR + (s << 5));
-  WizSpiBeginTransfer();
+  //return wiz_read_double(addr, WIZNET_READ_SnR + (s << 5));
+  wiz_spi_begin_transfer();
 
   // Send address
   word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  wiz_spi_transfer(addrMSB); //msByte
+  wiz_spi_transfer(addr); //lsByte
 
   word cb = WIZNET_READ_SnR + (s << 5);
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Read data
-  word retval = WizSpiTransfer(0) << 8;
-  retval = retval + WizSpiTransfer(0);
+  word retval = wiz_spi_transfer(0) << 8;
+  retval = retval + wiz_spi_transfer(0);
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 
   // Return read value
   return retval;
@@ -414,28 +414,28 @@ word wizGetSockReg16(word s, word addr)
 //-------------------
 
 // Initialize W5500 chip
-void wiz_Init(char* ip_addr, char* gateway_addr, char* mac_addr, char* sub_mask)
+void wiz_init(char* ip_addr, char* gateway_addr, char* mac_addr, char* sub_mask)
 {
   W5500_asmDefines(); // workaround to prevent deletion by optimizer
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
   delay(10);
 
-  wizWrite(WIZNET_SIPR,  WIZNET_WRITE_COMMON,  ip_addr,       4);
-  wizWrite(WIZNET_GAR,   WIZNET_WRITE_COMMON,  gateway_addr,  4);
-  wizWrite(WIZNET_SHAR,  WIZNET_WRITE_COMMON,  mac_addr,      6);
-  wizWrite(WIZNET_SUBR,  WIZNET_WRITE_COMMON,  sub_mask,      4);
+  wiz_write(WIZNET_SIPR,  WIZNET_WRITE_COMMON,  ip_addr,       4);
+  wiz_write(WIZNET_GAR,   WIZNET_WRITE_COMMON,  gateway_addr,  4);
+  wiz_write(WIZNET_SHAR,  WIZNET_WRITE_COMMON,  mac_addr,      6);
+  wiz_write(WIZNET_SUBR,  WIZNET_WRITE_COMMON,  sub_mask,      4);
 }
 
 
 // Initialize socket s for TCP
-void wizInitSocketTCP(word s, word port)
+void wiz_init_socket_tcp_host(word s, word port)
 {
-  wizCmd(s, WIZNET_CR_CLOSE);
-  wizSetSockReg8      (s, WIZNET_SnIR, 0xFF);    //reset interrupt register
-  wizSetSockReg8      (s, WIZNET_SnMR, WIZNET_MR_TCP);  //set mode register to tcp
-  wizSetSockReg16     (s, WIZNET_SnPORT, port);  //set tcp port
-  wizCmd(s, WIZNET_CR_OPEN);
-  wizCmd(s, WIZNET_CR_LISTEN);
+  wiz_send_cmd(s, WIZNET_CR_CLOSE);
+  wiz_set_sock_reg_8      (s, WIZNET_SnIR, 0xFF);    //reset interrupt register
+  wiz_set_sock_reg_8      (s, WIZNET_SnMR, WIZNET_MR_TCP);  //set mode register to tcp
+  wiz_set_sock_reg_16     (s, WIZNET_SnPORT, port);  //set tcp port
+  wiz_send_cmd(s, WIZNET_CR_OPEN);
+  wiz_send_cmd(s, WIZNET_CR_LISTEN);
   //delay(10); //wait a bit to make sure the socket is in the correct state (technically not necessary)
 }
 
@@ -447,7 +447,7 @@ void wizInitSocketTCP(word s, word port)
 
 
 // from memory, so no need for unsigned comparisons (because we have less than 2GB RAM)
-word wizWriteDataFromMemory(word s, char* buf, word buflen)
+word wiz_write_data(word s, char* buf, word buflen)
 {
   // Make sure there is something to send
   if (buflen <= 0)
@@ -461,7 +461,7 @@ word wizWriteDataFromMemory(word s, char* buf, word buflen)
   while (bytesSent != buflen)
   {
 
-    if (wizGetSockReg8(s, WIZNET_SnSR) == WIZNET_SOCK_CLOSED)
+    if (wiz_get_sock_reg_8(s, WIZNET_SnSR) == WIZNET_SOCK_CLOSED)
     {
       //uprintln("connection closed");
       return 0;
@@ -472,36 +472,36 @@ word wizWriteDataFromMemory(word s, char* buf, word buflen)
       partToSend = WIZNET_MAX_TBUF;
 
     // Make sure there is room in the transmit buffer for what we want to send
-    word txfree = wizGetSockReg16(s, WIZNET_SnTX_FSR); // Size of the available buffer area
+    word txfree = wiz_get_sock_reg_16(s, WIZNET_SnTX_FSR); // Size of the available buffer area
 
     word timeout = 0;
     while (txfree < partToSend) 
     {
       timeout++; // Increase timeout counter
       delay(1); // Wait a bit
-      txfree = wizGetSockReg16(s, WIZNET_SnTX_FSR); // Size of the available buffer area
+      txfree = wiz_get_sock_reg_16(s, WIZNET_SnTX_FSR); // Size of the available buffer area
       
       // After a second
       if (timeout > 1000) 
       {
-        wizCmd(s, WIZNET_CR_DISCON); // Disconnect the connection
+        wiz_send_cmd(s, WIZNET_CR_DISCON); // Disconnect the connection
         //uprintln("timeout");
         return 0;
       }
     }
 
      // Space is available so we will send the buffer
-    word txwr = wizGetSockReg16(s, WIZNET_SnTX_WR);  // Read the Tx Write Pointer
+    word txwr = wiz_get_sock_reg_16(s, WIZNET_SnTX_WR);  // Read the Tx Write Pointer
 
     // Write the outgoing data to the transmit buffer
-    wizWrite(txwr, WIZNET_WRITE_SnTX + (s << 5), buf + bytesSent, partToSend);
+    wiz_write(txwr, WIZNET_WRITE_SnTX + (s << 5), buf + bytesSent, partToSend);
 
     // update the buffer pointer
     word newSize = txwr + partToSend;
-    wizSetSockReg16(s, WIZNET_SnTX_WR, newSize);
+    wiz_set_sock_reg_16(s, WIZNET_SnTX_WR, newSize);
 
     // Now Send the SEND command which tells the wiznet the pointer is updated
-    wizCmd(s, WIZNET_CR_SEND);
+    wiz_send_cmd(s, WIZNET_CR_SEND);
 
     // Update the amount of bytes sent
     bytesSent += partToSend;
@@ -514,7 +514,7 @@ word wizWriteDataFromMemory(word s, char* buf, word buflen)
 
 
 // Read received data
-word wizReadRecvData(word s, char* buf, word buflen)
+word wiz_read_recv_data(word s, char* buf, word buflen)
 {
   if (buflen == 0)
   {
@@ -528,16 +528,16 @@ word wizReadRecvData(word s, char* buf, word buflen)
   }
    
   // Get the address where the wiznet is holding the data
-  word rxrd = wizGetSockReg16(s, WIZNET_SnRX_RD); 
+  word rxrd = wiz_get_sock_reg_16(s, WIZNET_SnRX_RD); 
 
   // Read the data into the buffer
-  wizRead(rxrd, WIZNET_READ_SnRX + (s << 5), buf, buflen);
+  wiz_read(rxrd, WIZNET_READ_SnRX + (s << 5), buf, buflen);
 
   // Remove read data from rxbuffer to make space for new data
   word nsize = rxrd + buflen;
-  wizSetSockReg16(s, WIZNET_SnRX_RD, nsize);  //replace read data pointer
+  wiz_set_sock_reg_16(s, WIZNET_SnRX_RD, nsize);  //replace read data pointer
   //tell the wiznet we have retrieved the data
-  wizCmd(s, WIZNET_CR_RECV);
+  wiz_send_cmd(s, WIZNET_CR_RECV);
 
   // Terminate buffer for printing in case the data was a string
   *(buf + buflen) = 0;
@@ -547,14 +547,14 @@ word wizReadRecvData(word s, char* buf, word buflen)
 
 
 // Remove the received data
-void wizFlush(word s, word rsize)
+void wiz_flush(word s, word rsize)
 {
   if (rsize > 0)
   {
-    word rxrd = wizGetSockReg16(s, WIZNET_SnRX_RD);         //retrieve read data pointer
+    word rxrd = wiz_get_sock_reg_16(s, WIZNET_SnRX_RD);         //retrieve read data pointer
     word nsize = rxrd + rsize;
-    wizSetSockReg16(s, WIZNET_SnRX_RD, nsize);  //replace read data pointer
+    wiz_set_sock_reg_16(s, WIZNET_SnRX_RD, nsize);  //replace read data pointer
     //tell the wiznet we have retrieved the data
-    wizCmd(s, WIZNET_CR_RECV);
+    wiz_send_cmd(s, WIZNET_CR_RECV);
   }
 }

+ 2 - 2
BCC/userBDOS/checksum.c

@@ -35,8 +35,6 @@ int main()
 
   // Get file size
   struct brfs_dir_entry* entry = (struct brfs_dir_entry*)fs_stat(absolute_path);
-  uprint("Entry address: ");
-  uprintlnHex((word)entry);
   if ((word)entry == -1)
   {
     bdos_println("File not found");
@@ -57,6 +55,8 @@ int main()
   word buffer[128];
   word read;
   word i;
+  // BUG: this will not work for files smaller than 128 words
+  // Look at webserv for better way
   while (filesize > 0)
   {
     read = fs_read(fd, (char*)buffer, 128);

+ 182 - 210
BCC/userBDOS/lib/wiz5500.c

@@ -3,11 +3,8 @@
 * Contains functions to allow for networking
 *
 * Functions from this library can be used to operate up to 8 sockets
-* Application based code should not be in this library
 */
 
-// uses stdlib.c
-
 // Wiznet W5500 Op Codes
 #define WIZNET_WRITE_COMMON 0x04 //opcode to write to one of the common block of registers
 #define WIZNET_READ_COMMON  0x00 //opcode to read one of the common block of registers
@@ -108,13 +105,14 @@
 #define WIZNET_MAX_RBUF 2048 // buffer for receiving data (max rx packet size!)
 #define WIZNET_MAX_TBUF 2048 // buffer for sending data (max tx packet size!)
 
+#define WIZNET_WAIT_BUFFER_TIMEOUT_MS 1000
 
 //-------------------
 //BASIC READ AND WRITE FUNCTIONS
 //-------------------
 
-// Sets SPI3_CS low
-void WizSpiBeginTransfer()
+// Set wiznet CS low
+void wiz_spi_begin_transfer()
 {
   asm(
       "; backup regs\n"
@@ -129,11 +127,11 @@ void WizSpiBeginTransfer()
       "; restore regs\n"
       "pop r2\n"
       "pop r1\n"
-      );
+    );
 }
 
-// Sets SPI3_CS high
-void WizSpiEndTransfer()
+// Set wiznet CS high
+void wiz_spi_end_transfer()
 {
   asm(
       "; backup regs\n"
@@ -148,13 +146,11 @@ void WizSpiEndTransfer()
       "; restore regs\n"
       "pop r2\n"
       "pop r1\n"
-      );
+    );
 }
 
-// write dataByte and return read value
-// write 0x00 for a read
-// Writes byte over SPI3 to W5500
-word WizSpiTransfer(word dataByte)
+// SPI write to wiznet chip
+word wiz_spi_transfer(word dataByte)
 {
   word retval = 0;
   asm(
@@ -162,142 +158,136 @@ word WizSpiTransfer(word dataByte)
       "write 0 r2 r4                      ; write r4 over SPI3\n"
       "read 0 r2 r2                       ; read return value\n"
       "write -4 r14 r2                    ; write to stack to return\n"
-      );
+    );
 
   return retval;
 }
 
-
 // Write data to W5500
-void wizWrite(word addr, word cb, char* buf, word len)
+void wiz_write(word addr, word cb, char *buf, word len)
 {
-  WizSpiBeginTransfer();
+  wiz_spi_begin_transfer();
 
   // Send address
-  word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  word addr_msb = (unsigned)addr >> 8;
+  wiz_spi_transfer(addr_msb);
+  wiz_spi_transfer(addr);
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Send data
   word i;
   for (i = 0; i < len; i++)
   {
-    WizSpiTransfer(buf[i]);
+    wiz_spi_transfer(buf[i]);
   }
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 }
 
-
 // Write single byte to W5500
-word wizWriteSingle(word addr, word cb, word data)
+word wiz_write_single(word addr, word cb, word data)
 {
-  WizSpiBeginTransfer();
+  wiz_spi_begin_transfer();
 
   // Send address
-  word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  word addr_msb = (unsigned)addr >> 8;
+  wiz_spi_transfer(addr_msb);
+  wiz_spi_transfer(addr);
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Send data
-  WizSpiTransfer(data);
+  wiz_spi_transfer(data);
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 
   return data;
 }
 
-
 // Write two bytes to W5500
-void wizWriteDouble(word addr, word cb, word data)
+void wiz_write_double(word addr, word cb, word data)
 {
-  WizSpiBeginTransfer();
+  wiz_spi_begin_transfer();
 
   // Send address
-  word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  word addr_msb = (unsigned)addr >> 8;
+  wiz_spi_transfer(addr_msb);
+  wiz_spi_transfer(addr);
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Send data
-  word dataMSB = (unsigned) data >> 8;
-  WizSpiTransfer(dataMSB);
-  WizSpiTransfer(data);
+  word dataMSB = (unsigned)data >> 8;
+  wiz_spi_transfer(dataMSB);
+  wiz_spi_transfer(data);
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 }
 
-
-void wizRead(word addr, word cb, char* buf, word len)
-{ 
-  WizSpiBeginTransfer();
+void wiz_read(word addr, word cb, char *buf, word len)
+{
+  wiz_spi_begin_transfer();
 
   // Send address
-  word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  word addr_msb = (unsigned)addr >> 8;
+  wiz_spi_transfer(addr_msb);
+  wiz_spi_transfer(addr);
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Read data
   word i;
   for (i = 0; i < len; i++)
   {
-    buf[i] = WizSpiTransfer(0);
+    buf[i] = wiz_spi_transfer(0);
   }
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 }
 
-
-word wizReadSingle(word addr, word cb)
-{ 
-  WizSpiBeginTransfer();
+word wiz_read_single(word addr, word cb)
+{
+  wiz_spi_begin_transfer();
 
   // Send address
-  word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  word addr_msb = (unsigned)addr >> 8;
+  wiz_spi_transfer(addr_msb);
+  wiz_spi_transfer(addr);
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Read data
-  word retval = WizSpiTransfer(0);
+  word retval = wiz_spi_transfer(0);
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 
   // Return read value
   return retval;
 }
 
-
-word wizReadDouble(word addr, word cb)
-{ 
-  WizSpiBeginTransfer();
+word wiz_read_double(word addr, word cb)
+{
+  wiz_spi_begin_transfer();
 
   // Send address
-  word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  word addr_msb = (unsigned)addr >> 8;
+  wiz_spi_transfer(addr_msb);
+  wiz_spi_transfer(addr);
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Read data
-  word retval = WizSpiTransfer(0) << 8;
-  retval = retval + WizSpiTransfer(0);
+  word retval = wiz_spi_transfer(0) << 8;
+  retval = retval + wiz_spi_transfer(0);
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 
   // Return read value
   return retval;
@@ -309,91 +299,88 @@ word wizReadDouble(word addr, word cb)
 //-------------------
 
 // Send a command cmd to socket s
-void wizCmd(word s, word cmd)
+void wiz_send_cmd(word s, word cmd)
 {
-  //wizWriteSingle(WIZNET_SnCR, WIZNET_WRITE_SnR, cmd);
-  WizSpiBeginTransfer();
-  WizSpiTransfer(0); //msByte
-  WizSpiTransfer(WIZNET_SnCR); //lsByte
-  WizSpiTransfer(WIZNET_WRITE_SnR + (s << 5));
-  WizSpiTransfer(cmd);
-  WizSpiEndTransfer();
-
-  // wait untill done
-  while ( wizReadSingle(WIZNET_SnCR, WIZNET_READ_SnR) );
+  wiz_spi_begin_transfer();
+  wiz_spi_transfer(0);
+  wiz_spi_transfer(WIZNET_SnCR);
+  wiz_spi_transfer(WIZNET_WRITE_SnR + (s << 5));
+  wiz_spi_transfer(cmd);
+  wiz_spi_end_transfer();
+
+  // Wait until done
+  while (wiz_read_single(WIZNET_SnCR, WIZNET_READ_SnR));
 }
 
 // Write 8 bits to a sockets control register
-void wizSetSockReg8(word s, word addr, word val)
+void wiz_set_sock_reg_8(word s, word addr, word val)
 {
-  //wizWriteSingle(addr, WIZNET_WRITE_SnR, val);
-  WizSpiBeginTransfer();
-  WizSpiTransfer(0); //msByte
-  WizSpiTransfer(addr); //lsByte
-  WizSpiTransfer(WIZNET_WRITE_SnR + (s << 5));
-  WizSpiTransfer(val);
-  WizSpiEndTransfer();
+  wiz_spi_begin_transfer();
+  wiz_spi_transfer(0);
+  wiz_spi_transfer(addr);
+  wiz_spi_transfer(WIZNET_WRITE_SnR + (s << 5));
+  wiz_spi_transfer(val);
+  wiz_spi_end_transfer();
 }
 
 // Read 8 bits from a sockets control register
-word wizGetSockReg8(word s, word addr){
-  //return wizReadSingle(addr, WIZNET_READ_SnR);
-  WizSpiBeginTransfer();
+word wiz_get_sock_reg_8(word s, word addr)
+{
+  wiz_spi_begin_transfer();
 
   // Send address
-  word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  word addr_msb = (unsigned) addr >> 8;
+  wiz_spi_transfer(addr_msb);
+  wiz_spi_transfer(addr);
 
   word cb = WIZNET_READ_SnR + (s << 5);
-  
+
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Read data
-  word retval = WizSpiTransfer(0);
+  word retval = wiz_spi_transfer(0);
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 
   // Return read value
   return retval;
 }
 
 // Write 16 bits to a sockets control register
-void wizSetSockReg16(word s, word addr, word val)
+void wiz_set_sock_reg_16(word s, word addr, word val)
 {
-  //wizWriteDouble(addr, WIZNET_WRITE_SnR + (s << 5), val);
-  WizSpiBeginTransfer();
-  WizSpiTransfer(0); //msByte
-  WizSpiTransfer(addr); //lsByte
-  WizSpiTransfer(WIZNET_WRITE_SnR + (s << 5));
-  word valMSB = (unsigned) val >> 8;
-  WizSpiTransfer(valMSB);
-  WizSpiTransfer(val);
-  WizSpiEndTransfer();
+  wiz_spi_begin_transfer();
+  wiz_spi_transfer(0);
+  wiz_spi_transfer(addr);
+  wiz_spi_transfer(WIZNET_WRITE_SnR + (s << 5));
+  word val_msb = (unsigned) val >> 8;
+  wiz_spi_transfer(val_msb);
+  wiz_spi_transfer(val);
+  wiz_spi_end_transfer();
 }
 
 // Read 16 bits from a sockets control register
-word wizGetSockReg16(word s, word addr)
+word wiz_get_sock_reg_16(word s, word addr)
 {
-  //return wizReadDouble(addr, WIZNET_READ_SnR + (s << 5));
-  WizSpiBeginTransfer();
+  //return wiz_read_double(addr, WIZNET_READ_SnR + (s << 5));
+  wiz_spi_begin_transfer();
 
   // Send address
-  word addrMSB = (unsigned) addr >> 8;
-  WizSpiTransfer(addrMSB); //msByte
-  WizSpiTransfer(addr); //lsByte
+  word addr_msb = (unsigned) addr >> 8;
+  wiz_spi_transfer(addr_msb);
+  wiz_spi_transfer(addr);
 
   word cb = WIZNET_READ_SnR + (s << 5);
 
   // Send control byte
-  WizSpiTransfer(cb);
+  wiz_spi_transfer(cb);
 
   // Read data
-  word retval = WizSpiTransfer(0) << 8;
-  retval = retval + WizSpiTransfer(0);
+  word retval = wiz_spi_transfer(0) << 8;
+  retval = retval + wiz_spi_transfer(0);
 
-  WizSpiEndTransfer();
+  wiz_spi_end_transfer();
 
   // Return read value
   return retval;
@@ -405,157 +392,142 @@ word wizGetSockReg16(word s, word addr)
 //-------------------
 
 // Initialize W5500 chip
-void wiz_Init(char* ip_addr, char* gateway_addr, char* mac_addr, char* sub_mask)
+void wiz_init(char *ip_addr, char *gateway_addr, char *mac_addr, char *sub_mask)
 {
-  WizSpiEndTransfer();
-  delay(10);
-
-  wizWrite(WIZNET_SIPR,  WIZNET_WRITE_COMMON,  ip_addr,       4);
-  wizWrite(WIZNET_GAR,   WIZNET_WRITE_COMMON,  gateway_addr,  4);
-  wizWrite(WIZNET_SHAR,  WIZNET_WRITE_COMMON,  mac_addr,      6);
-  wizWrite(WIZNET_SUBR,  WIZNET_WRITE_COMMON,  sub_mask,      4);
+  wiz_spi_end_transfer();
+  wiz_write(WIZNET_SIPR, WIZNET_WRITE_COMMON, ip_addr, 4);
+  wiz_write(WIZNET_GAR, WIZNET_WRITE_COMMON, gateway_addr, 4);
+  wiz_write(WIZNET_SHAR, WIZNET_WRITE_COMMON, mac_addr, 6);
+  wiz_write(WIZNET_SUBR, WIZNET_WRITE_COMMON, sub_mask, 4);
 }
 
-
-// Initialize socket s for TCP
-void wizInitSocketTCP(word s, word port)
+// Initialize socket s for TCP host mode
+void wiz_init_socket_tcp_host(word s, word port)
 {
-  wizCmd(s, WIZNET_CR_CLOSE);
-  wizSetSockReg8      (s, WIZNET_SnIR, 0xFF);    //reset interrupt register
-  wizSetSockReg8      (s, WIZNET_SnMR, WIZNET_MR_TCP);  //set mode register to tcp
-  wizSetSockReg16     (s, WIZNET_SnPORT, port);  //set tcp port
-  wizCmd(s, WIZNET_CR_OPEN);
-  wizCmd(s, WIZNET_CR_LISTEN);
-  delay(10); //wait a bit to make sure the socket is in the correct state (technically not necessary)
+  wiz_send_cmd(s, WIZNET_CR_CLOSE);
+  wiz_set_sock_reg_8(s, WIZNET_SnIR, 0xFF);          // Reset interrupt register
+  wiz_set_sock_reg_8(s, WIZNET_SnMR, WIZNET_MR_TCP); // Set mode register to tcp
+  wiz_set_sock_reg_16(s, WIZNET_SnPORT, port);       // Set tcp port
+  wiz_send_cmd(s, WIZNET_CR_OPEN);
+  wiz_send_cmd(s, WIZNET_CR_LISTEN);
+  while (wiz_get_sock_reg_8(s, WIZNET_SnSR) != WIZNET_SOCK_LISTEN);
 }
 
-
-// Initialize socket s for TCP client
-void wizInitSocketTCPClient(word s, word port)
+// Initialize socket s for TCP client mode
+void wiz_init_socket_tcp_client(word s, word port)
 {
-  wizCmd(s, WIZNET_CR_CLOSE);
-  wizSetSockReg8      (s, WIZNET_SnIR, 0xFF);    //reset interrupt register
-  wizSetSockReg8      (s, WIZNET_SnMR, WIZNET_MR_TCP);  //set mode register to tcp
-  wizSetSockReg16     (s, WIZNET_SnPORT, port);  //set tcp port
-  wizCmd(s, WIZNET_CR_OPEN);
-  delay(10); //wait a bit to make sure the socket is in the correct state (technically not necessary)
+  wiz_send_cmd(s, WIZNET_CR_CLOSE);
+  wiz_set_sock_reg_8(s, WIZNET_SnIR, 0xFF);          // Reset interrupt register
+  wiz_set_sock_reg_8(s, WIZNET_SnMR, WIZNET_MR_TCP); // Set mode register to tcp
+  wiz_set_sock_reg_16(s, WIZNET_SnPORT, port);       // Set tcp port
+  wiz_send_cmd(s, WIZNET_CR_OPEN);
+  while (wiz_get_sock_reg_8(s, WIZNET_SnSR) != WIZNET_SOCK_INIT);
 }
 
-
 //-------------------
 //W5500 READING AND WRITING FUNCTIONS
 //-------------------
 
-
-// from memory, so no need for unsigned comparisons (because we have less than 2GB RAM)
-word wizWriteDataFromMemory(word s, char* buf, word buflen)
+// Write data from buf of length buflen to socket s
+// Returns 1 if successful, 0 if not
+word wiz_write_data(word s, char *buf, word buflen)
 {
   // Make sure there is something to send
-  if (buflen <= 0)
+  if (buflen == 0)
   {
     return 0;
   }
 
-  word bytesSent = 0;
+  word bytes_sent = 0;
 
-  // loop until all bytes are sent
-  while (bytesSent != buflen)
+  // Loop until all bytes are sent
+  while (bytes_sent != buflen)
   {
-
-    if (wizGetSockReg8(s, WIZNET_SnSR) == WIZNET_SOCK_CLOSED)
+    if (wiz_get_sock_reg_8(s, WIZNET_SnSR) == WIZNET_SOCK_CLOSED)
     {
-      //uprintln("connection closed");
       return 0;
     }
 
-    word partToSend = buflen - bytesSent;
-    if (partToSend > WIZNET_MAX_TBUF)
-      partToSend = WIZNET_MAX_TBUF;
-
-    // Make sure there is room in the transmit buffer for what we want to send
-    word txfree = wizGetSockReg16(s, WIZNET_SnTX_FSR); // Size of the available buffer area
+    // Send in chunks of WIZNET_MAX_TBUF
+    word part_to_send = buflen - bytes_sent;
+    if (part_to_send > WIZNET_MAX_TBUF)
+    {
+      part_to_send = WIZNET_MAX_TBUF;
+    }
 
+    // Wait until there is room in the transmit buffer for what we want to send
+    word txfree = wiz_get_sock_reg_16(s, WIZNET_SnTX_FSR);
     word timeout = 0;
-    while (txfree < partToSend) 
+    while (txfree < part_to_send)
     {
-      timeout++; // Increase timeout counter
-      delay(1); // Wait a bit
-      txfree = wizGetSockReg16(s, WIZNET_SnTX_FSR); // Size of the available buffer area
-      
-      // After a second
-      if (timeout > 1000) 
+      timeout++;
+      delay(1);
+      txfree = wiz_get_sock_reg_16(s, WIZNET_SnTX_FSR);
+
+      if (timeout > WIZNET_WAIT_BUFFER_TIMEOUT_MS)
       {
-        wizCmd(s, WIZNET_CR_DISCON); // Disconnect the connection
-        //uprintln("timeout");
+        wiz_send_cmd(s, WIZNET_CR_DISCON); // Disconnect
         return 0;
       }
     }
 
-     // Space is available so we will send the buffer
-    word txwr = wizGetSockReg16(s, WIZNET_SnTX_WR);  // Read the Tx Write Pointer
+    // Read the Tx Write Pointer
+    word txwr = wiz_get_sock_reg_16(s, WIZNET_SnTX_WR);
 
     // Write the outgoing data to the transmit buffer
-    wizWrite(txwr, WIZNET_WRITE_SnTX + (s << 5), buf + bytesSent, partToSend);
+    wiz_write(txwr, WIZNET_WRITE_SnTX + (s << 5), buf + bytes_sent, part_to_send);
 
-    // update the buffer pointer
-    word newSize = txwr + partToSend;
-    wizSetSockReg16(s, WIZNET_SnTX_WR, newSize);
+    // Update the buffer pointer
+    word newSize = txwr + part_to_send;
+    wiz_set_sock_reg_16(s, WIZNET_SnTX_WR, newSize);
 
-    // Now Send the SEND command which tells the wiznet the pointer is updated
-    wizCmd(s, WIZNET_CR_SEND);
+    // Now send the SEND command which tells the wiznet the pointer is updated
+    wiz_send_cmd(s, WIZNET_CR_SEND);
 
     // Update the amount of bytes sent
-    bytesSent += partToSend;
+    bytes_sent += part_to_send;
   }
 
-
   return 1;
 }
 
-
-
-// Read received data
-word wizReadRecvData(word s, char* buf, word buflen)
+// Read received data on socket s of length buflen to buf
+void wiz_read_recv_data(word s, char *buf, word buflen)
 {
   if (buflen == 0)
   {
-    return 1;
+    return;
   }
-  
+
   if (buflen > WIZNET_MAX_RBUF) // If the request size > WIZNET_MAX_RBUF, truncate it to prevent overflow
   {
-    //uprintln("W: Received too large TCP data");
-    buflen = WIZNET_MAX_RBUF; // - 1; // -1 Because room for 0 terminator
+    buflen = WIZNET_MAX_RBUF;
   }
-   
+
   // Get the address where the wiznet is holding the data
-  word rxrd = wizGetSockReg16(s, WIZNET_SnRX_RD); 
+  word rxrd = wiz_get_sock_reg_16(s, WIZNET_SnRX_RD);
 
   // Read the data into the buffer
-  wizRead(rxrd, WIZNET_READ_SnRX + (s << 5), buf, buflen);
+  wiz_read(rxrd, WIZNET_READ_SnRX + (s << 5), buf, buflen);
 
   // Remove read data from rxbuffer to make space for new data
   word nsize = rxrd + buflen;
-    wizSetSockReg16(s, WIZNET_SnRX_RD, nsize);  //replace read data pointer
-    //tell the wiznet we have retrieved the data
-    wizCmd(s, WIZNET_CR_RECV);
+  wiz_set_sock_reg_16(s, WIZNET_SnRX_RD, nsize); // replace read data pointer
+  // Tell the wiznet we have retrieved the data
+  wiz_send_cmd(s, WIZNET_CR_RECV);
 
-  // Terminate buffer for printing in case the data was a string
-  *(buf + buflen) = 0;
-
-  return 1;
+  return;
 }
 
-
 // Remove the received data
-void wizFlush(word s, word rsize)
+void wiz_flush(word s, word rsize)
 {
   if (rsize > 0)
   {
-    word rxrd = wizGetSockReg16(s, WIZNET_SnRX_RD);         //retrieve read data pointer
+    word rxrd = wiz_get_sock_reg_16(s, WIZNET_SnRX_RD); // Retrieve read data pointer
     word nsize = rxrd + rsize;
-    wizSetSockReg16(s, WIZNET_SnRX_RD, nsize);  //replace read data pointer
-    //tell the wiznet we have retrieved the data
-    wizCmd(s, WIZNET_CR_RECV);
+    wiz_set_sock_reg_16(s, WIZNET_SnRX_RD, nsize); // Replace read data pointer
+    // Tell the wiznet we have retrieved the data
+    wiz_send_cmd(s, WIZNET_CR_RECV);
   }
 }

+ 0 - 593
BCC/userBDOS/toFix/webserv.c

@@ -1,593 +0,0 @@
-// Webserver
-// uses multiple sockets, except for socket 7 which is reserved by netHID
-
-#define word char
-
-#include "lib/math.c"
-#include "lib/stdlib.c"
-#include "lib/sys.c"
-#include "lib/fs.c"
-#include "lib/wiz5500.c"
-
-#define TMPMEM_LOCATION 0x440000
-#define FILE_BUFFER_LOCATION 0x430000
-#define FILE_BUFFER_SIZE 8192 // buffer size for reading files from USB storage
-
-char* fileBuffer = (char *) FILE_BUFFER_LOCATION; //fileBuffer[FILE_BUFFER_SIZE];
-char WIZrbuf[WIZNET_MAX_RBUF];
-
-//-------------------
-//LIST DIR CUSTOM FUNCTIONS
-//-------------------
-
-// Parses and writes name.extension and filesize on one line
-void wiz_parseFATdata(word datalen, char* fatBuffer, char* b, word* bufLen)
-{
-  if (datalen != 32)
-  {
-    BDOS_PrintConsole("Unexpected FAT table length\n");
-    return;
-  }
-
-  // start HTML link tag
-  word catLen = strcpy(b + *bufLen, "<tr><td style=\"padding:0 15px 0 15px;\"><a href=\"");
-  (*bufLen) += catLen;
-
-  // parse filename
-  word printLen = FS_parseFATstring(fatBuffer, 8, b, bufLen);
-
-  // add '.' and parse extension
-  if (fatBuffer[8] != ' ' || fatBuffer[9] != ' ' || fatBuffer[10] != ' ')
-  {
-    b[*bufLen] = '.';
-    (*bufLen)++;
-    printLen += FS_parseFATstring(fatBuffer+8, 3, b, bufLen) + 1;
-  }
-
-  // filesize
-  word fileSize = 0;
-  fileSize += fatBuffer[28];
-  fileSize += (fatBuffer[29] << 8);
-  fileSize += (fatBuffer[30] << 16);
-  fileSize += (fatBuffer[31] << 24);
-
-  // add slash if folder (filesize 0)
-  if (fileSize == 0)
-  {
-    catLen = strcpy(b + *bufLen, "/");
-    (*bufLen) += catLen;
-  }
-
-  // end the starting HTML link tag
-  catLen = strcpy(b + *bufLen, "\">");
-  (*bufLen) += catLen;
-
-  // do again for the link text
-  // parse filename
-  printLen = FS_parseFATstring(fatBuffer, 8, b, bufLen);
-
-  // add '.' and parse extension
-  if (fatBuffer[8] != ' ' || fatBuffer[9] != ' ' || fatBuffer[10] != ' ')
-  {
-    b[*bufLen] = '.';
-    (*bufLen)++;
-    printLen += FS_parseFATstring(fatBuffer+8, 3, b, bufLen) + 1;
-  }
-
-  // add slash if folder (filesize 0)
-  if (fileSize == 0)
-  {
-    catLen = strcpy(b + *bufLen, "/");
-    (*bufLen) += catLen;
-  }
-
-  // end hyperlink
-  catLen = strcpy(b + *bufLen, "</a></td><td style=\"padding:0 15px 0 15px;\">");
-  (*bufLen) += catLen;
-
-  
-
-  // filesize to integer string
-  char buffer[10];
-  itoa(fileSize, &buffer[0]);
-
-  // write to buffer
-  word i = 0;
-  while (buffer[i] != 0)
-  {
-    b[*bufLen] = buffer[i];
-    (*bufLen)++;
-    i++;
-  }
-
-  catLen = strcpy(b + *bufLen, "</td></tr>\n");
-  (*bufLen) += catLen;
-}
-
-
-// Reads FAT data for single entry
-// FAT data is parsed by FS_parseFatData()
-void wiz_readFATdata(char* b, word* bufLen)
-{
-  FS_spiBeginTransfer();
-  FS_spiTransfer(FS_CMD_RD_USB_DATA0);
-  word datalen = FS_spiTransfer(0x0);
-  char fatbuf[32];
-  word i;
-  for (i = 0; i < datalen; i++)
-  {
-    fatbuf[i] = FS_spiTransfer(0x00);
-  }
-  wiz_parseFATdata(datalen, fatbuf, b, bufLen);
-  FS_spiEndTransfer();
-}
-
-// Lists directory of full path f
-// f needs to start with / and not end with /
-// Returns ANSW_USB_INT_SUCCESS if successful
-// Writes parsed result to address b
-// Result is terminated with a \0
-word wiz_listDir(char* f, char* b)
-{
-  word bufLen = 0;
-  word* pBuflen = &bufLen;
-
-  word retval = FS_sendFullPath(f);
-  // Return on failure
-  if (retval != FS_ANSW_USB_INT_SUCCESS)
-    return retval;
-
-  retval = FS_open();
-  // Return on failure
-  if (retval != FS_ANSW_USB_INT_SUCCESS && retval != FS_ANSW_ERR_OPEN_DIR)
-    return retval;
-
-  FS_sendSinglePath("*");
-
-  retval = FS_open();
-  // Return on failure
-  if (retval != FS_ANSW_USB_INT_DISK_READ)
-    return retval;
-
-  // Init length of output buffer
-  *pBuflen = 0;
-
-  while (retval == FS_ANSW_USB_INT_DISK_READ)
-  {
-    wiz_readFATdata(b, pBuflen);
-    FS_spiBeginTransfer();
-    FS_spiTransfer(FS_CMD_FILE_ENUM_GO);
-    FS_spiEndTransfer();
-    retval = FS_WaitGetStatus();
-  }
-
-  // Terminate buffer
-  b[*pBuflen] = 0;
-  (*pBuflen)++;
-
-  return FS_ANSW_USB_INT_SUCCESS;
-}
-
-
-word PercentageDone(word remaining, word full)
-{
-  word x = remaining * 100;
-  return 100 - MATH_divU(x, full);
-}
-
-//-------------------
-//W5500 CONNECTION HANDLING FUNCTIONS
-//-------------------
-
-// Writes response from (successfully) opened USB file
-word wizWriteResponseFromUSB(word s, word fileSize)
-{
-  // file size is already checked on being > 0
-
-  if (FS_setCursor(0) != FS_ANSW_USB_INT_SUCCESS)
-    BDOS_PrintConsole("cursor error\n");
-
-  word bytesSent = 0;
-  char buffer[10];
-
-  char dbuf[10]; // percentage done for progress indication
-  dbuf[0] = 0; // terminate
-
-  // loop until all bytes are sent
-  while (bytesSent != fileSize)
-  {
-    word partToSend = fileSize - bytesSent;
-    // send in parts of FILE_BUFFER_SIZE
-    if (partToSend > FILE_BUFFER_SIZE)
-      partToSend = FILE_BUFFER_SIZE;
-
-    // read from usb to buffer
-    if (FS_readFile(fileBuffer, partToSend, 0) != FS_ANSW_USB_INT_SUCCESS)
-      BDOS_PrintConsole("read error\n");
-    if (!wizWriteDataFromMemory(s, fileBuffer, partToSend))
-    {
-      //uprintln("wizTranser error");
-      return 0;
-    }
-
-    // Update the amount of bytes sent
-    bytesSent += partToSend;
-
-    //BDOS_PrintConsole(".");
-
-    // indicate progress
-    // remove previous percentage
-    word i = strlen(dbuf);
-    while (i > 0)
-    {
-      BDOS_PrintcConsole(0x8); // backspace
-      i--;
-    }
-    if (strlen(dbuf) != 0)
-    {
-      BDOS_PrintcConsole(0x8); // backspace
-    }
-
-    itoa(PercentageDone(fileSize - bytesSent, fileSize), dbuf);
-    BDOS_PrintConsole(dbuf);
-    BDOS_PrintcConsole('%');
-  }
-
-  // remove previous percentage
-  word i = strlen(dbuf);
-  while (i > 0)
-  {
-    BDOS_PrintcConsole(0x8); // backspace
-    i--;
-  }
-  if (strlen(dbuf) != 0)
-  {
-    BDOS_PrintcConsole(0x8); // backspace
-  }
-
-  FS_close();
-  return 1;
-}
-
-
-void wizSend404Response(word s)
-{
-  char* retTxt = "<!DOCTYPE html><html><head><title>ERROR404</title></head><body>ERROR 404: This is not the page you are looking for</body></html>";
-  wizWriteDataFromMemory(s, retTxt, strlen(retTxt));
-}
-
-
-// Gets requested file path from request header
-// Returns size of requested path (should be 1 or higher because '/')
-// Fills pbuf with path
-// Assumes a request header of appropiate size
-word wizGetFilePath(char* rbuf, char* pbuf)
-{
-  word foundPath = 0;
-  word foundSpace = 0;
-  word cursor = 0;
-  word pathIndex = 0;
-
-  while (foundPath == 0)
-  {
-    // until we found the first space after GET (or POST)
-    if (foundSpace == 0 && rbuf[cursor] == 32)
-    {
-      foundSpace = 1;
-    }
-    else 
-    {
-      if (foundSpace == 1)
-      {
-        // until we found the second space (after the file path)
-        if (rbuf[cursor] == 32)
-        {
-          // exit the loop, we are done
-          foundPath = 1;
-        }
-        else
-        {
-          // copy the character
-          pbuf[pathIndex] = rbuf[cursor];
-          //uprintc(rbuf[cursor]);
-          pathIndex++;
-        }
-      }
-    }
-    // go to next character
-    cursor++;
-  }
-
-  pbuf[pathIndex] = 0; // terminate string
-
-  // return the path length
-  return (pathIndex + 1);
-}
-
-
-void wizDirectoryListing(word s, char* path)
-{
-
-  // write start of html page
-  wizWriteDataFromMemory(s, "<!DOCTYPE html><html><body><h2>", 31);
-
-  word pathLen = 0;
-  while (path[pathLen] != 0)
-    pathLen++;
-
-  wizWriteDataFromMemory(s, path, pathLen-1);
-
-  wizWriteDataFromMemory(s, "</h2><table><tr><th>Name</th><th>Size</th></tr>", 47);
-
-
-  char *b = (char *) TMPMEM_LOCATION;
-  if (wiz_listDir(path, b) == FS_ANSW_USB_INT_SUCCESS)
-  {
-    word listSize = 0;
-    while (b[listSize] != 0)
-      listSize++;
-
-    if (listSize == 0)
-      listSize = 1;
-
-    wizWriteDataFromMemory(s, b, listSize-1);
-  }
-
-  // write end of html page
-  wizWriteDataFromMemory(s, "</table></body></html>", 22);
-}
-
-
-void wizServeFile(word s, char* path)
-{
-  BDOS_PrintConsole(path);
-  BDOS_PrintConsole(": ");
-
-  // Redirect "/" to "/INDEX.HTM"
-  if (path[0] == 47 && path[1] == 0)
-  {
-    // send an actual redirect to the browser
-    char* response = "HTTP/1.1 301 Moved Permanently\nLocation: /INDEX.HTM\n";
-    BDOS_PrintConsole("Redirect to /INDEX.HTM\n");
-    wizWriteDataFromMemory(s, response, strlen(response));
-    // Disconnect after sending the redirect
-    wizCmd(s, WIZNET_CR_DISCON);
-    return;
-  }
-
-  word error = 0;
-  word listDir = 0;
-
-  if (FS_sendFullPath(&path[0]) != FS_ANSW_USB_INT_SUCCESS) // automatically upercases the path
-    error = 404;
-
-  if (!error)
-  {
-    word openStatus = FS_open();
-    if (openStatus == FS_ANSW_ERR_OPEN_DIR)
-      listDir = 1;
-    else if (openStatus != FS_ANSW_USB_INT_SUCCESS)
-      error = 404;
-  }
-
-  word fileSize = 0;
-  if (!error && !listDir)
-    fileSize = FS_getFileSize();
-
-  if (!error && !listDir)
-  {
-    if (fileSize == 0)
-      error = 404; // handle empty files as if they do not exist
-  }
-
-  // send error response on error
-  if (error)
-  {
-    BDOS_PrintConsole("404 ");
-    // currently puts all errors under 404
-    // write header
-    char* header = "HTTP/1.1 404 Not Found\nServer: FPGC/1.0\nContent-Type: text/html\n\n";
-    wizWriteDataFromMemory(s, header, strlen(header));
-
-    FS_sendFullPath("/404.HTM");
-    if (FS_open() != FS_ANSW_USB_INT_SUCCESS)
-    {
-      // if the custom 404 does not exist, return own error code
-      BDOS_PrintConsole("no 404.HTM\n");
-      wizSend404Response(s);
-    }
-    else
-    {
-      // send custom 404
-      fileSize = FS_getFileSize();
-      // write the response from USB
-      BDOS_PrintConsole("/404.HTM ");
-      wizWriteResponseFromUSB(s, fileSize);
-      BDOS_PrintConsole("Done\n");
-    }
-  }
-  else
-  {
-    if (listDir)
-    {
-      // check if last character is a /
-      // if not, redirect to the path with / after it
-      word i = 0;
-      while (path[i] != 0)
-        i++;
-
-      if (path[i-1] != '/')
-      {
-        //BDOS_PrintConsole(path);
-        //BDOS_PrintConsole("\n");
-        path[i] = '/';
-        path[i+1] = 0;
-        char* response = "HTTP/1.1 301 Moved Permanently\nLocation: ";
-        BDOS_PrintConsole("Redirect to ");
-        BDOS_PrintConsole(path);
-        BDOS_PrintConsole("\n");
-        wizWriteDataFromMemory(s, response, strlen(response));
-        wizWriteDataFromMemory(s, path, i+1);
-        wizWriteDataFromMemory(s, "\n", 1);
-      }
-      else
-      {
-        BDOS_PrintConsole("200 ");
-        // write header
-        // currently omitting content type
-        char* header = "HTTP/1.1 200 OK\nServer: FPGC/1.0\n\n";
-        wizWriteDataFromMemory(s, header, strlen(header));
-        wizDirectoryListing(s, path);
-        BDOS_PrintConsole("Done\n");
-      }
-    }
-    else
-    {
-      if (fileSize + 1 != 0) // really make sure no directory is being read
-      {
-        BDOS_PrintConsole("200 ");
-        // write header
-        // currently omitting content type
-        // includes content length so the client knows how large a download is
-        char header[128];
-        header[0] = 0;
-        strcat(header, "HTTP/1.1 200 OK\nServer: FPGC/1.0\nContent-Length: ");
-        char fileSizeStr[24];
-        itoa(fileSize, fileSizeStr);
-        strcat(header, fileSizeStr);
-        strcat(header, "\n\n");
-        wizWriteDataFromMemory(s, header, strlen(header));
-        // write the response from USB
-        wizWriteResponseFromUSB(s, fileSize);
-        BDOS_PrintConsole("Done\n");
-      }
-      
-    }
-  }
-
-  // Disconnect after sending a response
-  wizCmd(s, WIZNET_CR_DISCON);
-} 
-
-
-
-
-
-// Handle session for socket s
-void wizHandleSession(word s)
-{
-  // Size of received data
-  word rsize;
-  rsize = wizGetSockReg16(s, WIZNET_SnRX_RSR);
-
-  if (rsize == 0)
-  {
-    wizCmd(s, WIZNET_CR_DISCON);
-    return;
-  }
-
-  char* rbuf = WIZrbuf;
-  wizReadRecvData(s, rbuf, rsize);
-
-  //  read rbuf for requested page
-  //  parse from {GET /INFO.HTM HTTP/1.1}
-  char pbuf[128]; // buffer for path name
-  word pbufSize = wizGetFilePath(&rbuf[1], pbuf);
-
-  wizServeFile(s, pbuf);
-
-  // Free received data when not read
-  // Not used, since we currently read the request
-  //wizFlush(s, rsize);
-
-}
-
-
-
-int main() 
-{
-
-  BDOS_PrintConsole("Starting Web Server\n");
-
-  // Assumes that the USB drive is already properly initialized by BDOS
-
-  word ip_addr[4] = {192, 168, 0, 213};
-
-  word gateway_addr[4] = {192, 168, 0, 1};
-
-  word mac_addr[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0x24, 0x64};
-
-  word sub_mask[4] = {255, 255, 255, 0};
-
-  wiz_Init(ip_addr, gateway_addr, mac_addr, sub_mask);
-
-  // Open all sockets in TCP Server mode at port 80
-  wizInitSocketTCP(0, 80);
-  wizInitSocketTCP(1, 80);
-  wizInitSocketTCP(2, 80);
-  wizInitSocketTCP(3, 80);
-  wizInitSocketTCP(4, 80);
-  wizInitSocketTCP(5, 80);
-  wizInitSocketTCP(6, 80);
-
-  // Socket s status
-  word sxStatus;
-
-  while(1)
-  {
-    if (HID_FifoAvailable())
-    {
-      HID_FifoRead(); // remove it from the buffer
-      return 'q';
-    }
-    // handle all sockets (socket 7 is reserved by netHID)
-    word s;
-    for (s = 0; s < 7; s++)
-    {
-      // Get status for socket s
-      sxStatus = wizGetSockReg8(s, WIZNET_SnSR);
-
-      if (sxStatus == WIZNET_SOCK_CLOSED)
-      { 
-        // Open the socket when closed
-        // Set socket s in TCP Server mode at port 80
-        wizInitSocketTCP(s, 80);
-      }
-      else if (sxStatus == WIZNET_SOCK_ESTABLISHED)
-      {
-        // Handle session when a connection is established
-        // Also reinitialize socket
-        wizHandleSession(s);
-        // Set socket s in TCP Server mode at port 80
-        wizInitSocketTCP(s, 80);
-      }
-      else if (sxStatus == WIZNET_SOCK_LISTEN || sxStatus == WIZNET_SOCK_SYNSENT || sxStatus == WIZNET_SOCK_SYNRECV)
-      {
-        // Do nothing in these cases
-      }
-      else
-      {
-        // In other cases, reset the socket
-        // Set socket s in TCP Server mode at port 80
-        wizInitSocketTCP(s, 80);
-      }
-    }
-    // Delay a few milliseconds
-    // Should (could) eventually be replaced by an interrupt checker
-    delay(10);
-  }
-
-  return 'q';
-}
-
-void interrupt()
-{
-  // Handle all interrupts
-  word i = getIntID();
-  switch(i)
-  {
-    case INTID_TIMER1:
-      timer1Value = 1;  // Notify ending of timer1
-      break;
-  }
-}

+ 12 - 12
BCC/userBDOS/toFix/wget.c

@@ -29,10 +29,10 @@ void initClient(word ip, word port)
 
   word sub_mask[4] = {255, 255, 255, 0};
 
-  wiz_Init(ip_addr, gateway_addr, mac_addr, sub_mask);
+  wiz_init(ip_addr, gateway_addr, mac_addr, sub_mask);
 
   // Open socket in TCP Client mode at port
-  wizInitSocketTCPClient(SOCKET_CLIENT, port);
+  wiz_init_socket_tcp_client(SOCKET_CLIENT, port);
 }
 
 
@@ -40,11 +40,11 @@ void initClient(word ip, word port)
 // Return 1 on success, 0 on failure
 word connectToTarget(char* ipTarget, word portTarget)
 {
-  wizWrite(WIZNET_SnDIPR,  WIZNET_WRITE_SnR + (SOCKET_CLIENT << 5), ipTarget, 4);
-  wizSetSockReg16(SOCKET_CLIENT, WIZNET_SnDPORT, portTarget);
-  wizCmd(SOCKET_CLIENT, WIZNET_CR_CONNECT);
+  wiz_write(WIZNET_SnDIPR,  WIZNET_WRITE_SnR + (SOCKET_CLIENT << 5), ipTarget, 4);
+  wiz_set_sock_reg_16(SOCKET_CLIENT, WIZNET_SnDPORT, portTarget);
+  wiz_send_cmd(SOCKET_CLIENT, WIZNET_CR_CONNECT);
 
-  word sxStatus = wizGetSockReg8(SOCKET_CLIENT, WIZNET_SnSR);
+  word sxStatus = wiz_get_sock_reg_8(SOCKET_CLIENT, WIZNET_SnSR);
 
   word retries = 0;
 
@@ -56,7 +56,7 @@ word connectToTarget(char* ipTarget, word portTarget)
       return 0;
     }
 
-    sxStatus = wizGetSockReg8(SOCKET_CLIENT, WIZNET_SnSR);
+    sxStatus = wiz_get_sock_reg_8(SOCKET_CLIENT, WIZNET_SnSR);
 
     if (sxStatus != WIZNET_SOCK_ESTABLISHED)
     {
@@ -96,7 +96,7 @@ void sendRequest()
   catLen = strcpy(rTxt + rLen, "\r\n\r\n");
   rLen += catLen;
 
-  wizWriteDataFromMemory(SOCKET_CLIENT, rTxt, rLen);
+  wiz_write_data(SOCKET_CLIENT, rTxt, rLen);
   BDOS_PrintConsole("Request sent\n");
 }
 
@@ -277,13 +277,13 @@ void receiveResponse(char* path, char* fname)
   word currentProgress = 0;
 
   BDOS_PrintConsole("Downloading response (any key to stop)\n");
-  while (wizGetSockReg8(SOCKET_CLIENT, WIZNET_SnSR) == WIZNET_SOCK_ESTABLISHED)
+  while (wiz_get_sock_reg_8(SOCKET_CLIENT, WIZNET_SnSR) == WIZNET_SOCK_ESTABLISHED)
   {
-    word rsize = wizGetSockReg16(SOCKET_CLIENT, WIZNET_SnRX_RSR);
+    word rsize = wiz_get_sock_reg_16(SOCKET_CLIENT, WIZNET_SnRX_RSR);
     if (rsize != 0)
     {
       char* rbuf = (char*) HEAP_LOCATION; // we use heap for the receive data buffer
-      wizReadRecvData(SOCKET_CLIENT, rbuf, rsize);
+      wiz_read_recv_data(SOCKET_CLIENT, rbuf, rsize);
       if (firstResponse)
       {
         word dataStart = getDataStart(rbuf, rsize);
@@ -335,7 +335,7 @@ void receiveResponse(char* path, char* fname)
       break;
     }
   }
-  wizCmd(SOCKET_CLIENT, WIZNET_CR_DISCON);
+  wiz_send_cmd(SOCKET_CLIENT, WIZNET_CR_DISCON);
   BDOS_PrintConsole("Output written to ");
   BDOS_PrintConsole(path);
   BDOS_PrintConsole("/");

+ 462 - 0
BCC/userBDOS/webserv.c

@@ -0,0 +1,462 @@
+/**
+ * Webserver for the FPGC
+ * Uses multiple sockets to handle multiple connections (except for socket 7 which is reserved by netHID)
+ * Note that all files are stored in the filesystem per word and not in bytes
+ *  So currently the only the rightmost byte of each file are sent over the network
+ *  This is to stay compatible with text files
+*/
+
+#define word char
+
+#include "lib/math.c"
+#include "lib/stdlib.c"
+#include "lib/sys.c"
+#include "lib/brfs.c"
+#include "lib/wiz5500.c"
+
+#define WIZNET_IP 213
+
+char wiz_rbuf[WIZNET_MAX_RBUF];
+
+word percentage_done(word remaining, word full)
+{
+  word x = remaining * 100;
+  return 100 - MATH_divU(x, full);
+}
+
+/**
+ * Write a file from the filesystem to a socket
+ * Sends the file in parts of WIZNET_MAX_TBUF
+ * Assumes the filepath is valid
+*/
+void write_file_from_fs(word s, char* path, word filesize)
+{
+  // Open the file
+  word fd = fs_open(path);
+  if (fd == -1)
+  {
+    // Should not happen
+    bdos_println("UNEXPECTED: File not found!");
+    return;
+  }
+
+  word fullsize = filesize;
+
+  // Read file in chunks of WIZNET_MAX_TBUF
+  word file_buffer[WIZNET_MAX_RBUF];
+  word chunk_to_read;
+
+  char dbuf[10]; // Percentage done for progress indication
+  dbuf[0] = 0;
+
+  while (filesize > 0)
+  {
+    chunk_to_read = filesize > WIZNET_MAX_RBUF ? WIZNET_MAX_RBUF : filesize;
+    fs_read(fd, (char*)file_buffer, chunk_to_read);
+    wiz_write_data(s, file_buffer, chunk_to_read);
+    filesize -= chunk_to_read;
+
+    // Calculate percentage done
+    word percentage = percentage_done(filesize, fullsize);
+
+    // Remove previous percentage
+    word i = strlen(dbuf);
+    while (i > 0)
+    {
+      bdos_printc(0x8); // Backspace
+      i--;
+    }
+    if (strlen(dbuf) != 0)
+    {
+      bdos_printc(0x8); // Backspace
+    }
+    itoa(percentage, dbuf);
+    bdos_print(dbuf);
+    bdos_printc('%');
+  }
+
+  bdos_printc(' '); // Add space after percentage
+
+  // Close file
+  fs_close(fd);
+}
+
+
+/**
+ * Send a 404 response
+ * Could be extended by sending a custom 404 page if found in the filesystem
+*/
+void send_404_response(word s)
+{
+  char* response_header = "HTTP/1.1 404 Not Found\nServer: FPGC/2.0\nContent-Type: text/html\n\n";
+  wiz_write_data(s, response_header, strlen(response_header));
+  char* response_body = "<!DOCTYPE html><html><head><title>ERROR404</title></head><body>ERROR 404: Could not find the requested file or directory :(</body></html>";
+  wiz_write_data(s, response_body, strlen(response_body));
+  // Disconnect after sending a response
+  wiz_send_cmd(s, WIZNET_CR_DISCON);
+}
+
+
+/**
+ * Parse the file path from a request header in rbuf
+ * Writes field to pbuf
+ * File path is assumed to be the second word in the request header
+*/
+void parse_file_path(char* rbuf, char* pbuf)
+{
+  strtok(rbuf, " "); // Skip the first word
+  char* file_path = strtok((char*)-1, " ");
+
+  if ((word)file_path != -1 && strlen(file_path) < MAX_PATH_LENGTH)
+  {
+    strcpy(pbuf, file_path);
+  }
+  else
+  {
+    strcpy(pbuf, "/");
+  }
+}
+
+/**
+ * Send directory listing to socket s as part of send_dir
+ * Only sends the body of the response and should not disconnect the socket
+ * Assumes path is a valid directory
+*/
+void send_list_dir(word s, char* path)
+{
+  // Write start of html page
+  char* html_start = "<!DOCTYPE html><html><body><h2>";
+  wiz_write_data(s, html_start, strlen(html_start));
+
+  // Print path as header
+  wiz_write_data(s, path, strlen(path));
+
+  // Start table
+  char* table_start = "</h2><table><tr><th>Name</th><th>Size</th></tr>";
+  wiz_write_data(s, table_start, strlen(table_start));
+
+  // Obtain directory entries
+  struct brfs_dir_entry entries[MAX_DIR_ENTRIES];
+  word num_entries = fs_readdir(path, (char*)entries);
+
+  // Keep track of the longest filename for formatting
+  word max_filename_length = 0;
+
+  // Sort entries by filename
+  word i, j;
+  for (i = 0; i < num_entries - 1; i++)
+  {
+    for (j = 0; j < num_entries - i - 1; j++)
+    {
+      char decompressed_filename1[17];
+      strdecompress(decompressed_filename1, entries[j].filename);
+
+      char decompressed_filename2[17];
+      strdecompress(decompressed_filename2, entries[j + 1].filename);
+
+      // Update max_filename_length
+      // This works because . is always the first entry (skipped by this check)
+      if (strlen(decompressed_filename2) > max_filename_length)
+      {
+        max_filename_length = strlen(decompressed_filename2);
+      }
+
+      // Sort by filename
+      if (strcmp(decompressed_filename1, decompressed_filename2) > 0)
+      {
+        // Swap filenames
+        struct brfs_dir_entry temp = entries[j];
+        entries[j] = entries[j + 1];
+        entries[j + 1] = temp;
+      }
+    }
+  }
+
+  // Loop through sorted entries and print them
+  for (i = 0; i < num_entries; i++)
+  {
+    // Send start of table row
+    char* table_row_start = "<tr><td style=\"padding:0 15px 0 15px;\"><a href=\"";
+    wiz_write_data(s, table_row_start, strlen(table_row_start));
+
+    // Create entry string
+    char entry_str[128];
+
+    // Add filename
+    struct brfs_dir_entry entry = entries[i];
+    char filename[17];
+    strdecompress(filename, entry.filename);
+    strcpy(entry_str, filename);
+
+    // Add / if directory
+    if ((entry.flags & 0x01) == 1)
+    {
+      strcat(entry_str, "/");
+    }
+
+    // Add end of HTML link tag
+    strcat(entry_str, "\">");
+
+    // Add filename again for the link text
+    strcat(entry_str, filename);
+    if ((entry.flags & 0x01) == 1)
+    {
+      strcat(entry_str, "/");
+    }
+
+    // End the hyperlink
+    strcat(entry_str, "</a></td><td style=\"padding:0 15px 0 15px;\">");
+
+    // Add filesize if file
+    if ((entry.flags & 0x01) == 0)
+    {
+      char filesize_str[11];
+      itoa(entry.filesize, filesize_str);
+      strcat(entry_str, filesize_str);
+    }
+
+    // End the table row
+    strcat(entry_str, "</td></tr>\n");
+    
+    // Write the entry to the socket
+    wiz_write_data(s, entry_str, strlen(entry_str));
+  }
+
+  // write end of html page
+  wiz_write_data(s, "</table></body></html>", 22);
+}
+
+/**
+ * Serve a file
+ * Sends the response to socket s
+ * Includes the content length in the header so the client knows how large a download is
+ * Assumes the file is valid
+*/
+void serve_file(word s, char* path)
+{
+  // Get file size
+  struct brfs_dir_entry* entry = (struct brfs_dir_entry*)fs_stat(path);
+  if ((word)entry == -1)
+  {
+    // Should not happen, so just disconnect the session
+    bdos_println("UNEXPECTED: File not found!");
+    wiz_send_cmd(s, WIZNET_CR_DISCON);
+  }
+  word filesize = entry->filesize;
+
+  bdos_print("200 ");
+
+  // Write header (currently omitting content type)
+  char header[128];
+  strcpy(header, "HTTP/1.1 200 OK\nServer: FPGC/2.0\nContent-Length: ");
+  
+  char filesize_str[12];
+  itoa(filesize, filesize_str);
+  strcat(header, filesize_str);
+  strcat(header, "\n\n");
+
+  wiz_write_data(s, header, strlen(header));
+
+  // Write the response from filesystem
+  write_file_from_fs(s, path, filesize);
+  bdos_println("Done");
+
+  // Disconnect after sending a response
+  wiz_send_cmd(s, WIZNET_CR_DISCON);
+}
+
+/**
+ * Serve a directory
+ * Sends the response to socket s
+ * Assumes the directory is valid
+*/
+void serve_dir(word s, char* path)
+{
+  // If path does not end with a slash, redirect to the same path with a slash
+  if (path[strlen(path) - 1] != '/')
+  {
+    strcat(path, "/");
+    char* response = "HTTP/1.1 301 Moved Permanently\nLocation: ";
+    bdos_print("Redirect to ");
+    bdos_println(path);
+    wiz_write_data(s, response, strlen(response));
+    wiz_write_data(s, path, strlen(path));
+    wiz_write_data(s, "\n", 1);
+  }
+  else
+  {
+    bdos_print("200 ");
+    // Write header (currently omitting content type)
+    char* header = "HTTP/1.1 200 OK\nServer: FPGC/2.0\n\n";
+    wiz_write_data(s, header, strlen(header));
+    send_list_dir(s, path);
+    bdos_println("Done");
+  }
+
+  // Disconnect after sending a response
+  wiz_send_cmd(s, WIZNET_CR_DISCON);
+}
+
+/**
+ * Serve a path from the file system
+ * Sends the response to socket s
+*/
+void serve_path(word s, char* path)
+{
+  // Redirect "/" to "/index.html"
+  if (strcmp(path, "/") == 0)
+  {
+    // Send an actual redirect to the browser
+    char *response = "HTTP/1.1 301 Moved Permanently\nLocation: /index.html\n";
+    bdos_println("Redirect to /index.html\n");
+    wiz_write_data(s, response, strlen(response));
+
+    // Disconnect after sending the redirect
+    wiz_send_cmd(s, WIZNET_CR_DISCON);
+    return;
+  }
+
+  // Check if the path is a directory
+  char path_copy[MAX_PATH_LENGTH];
+  strcpy(path_copy, path); // Make a copy as stat remove trailing slashes
+  struct brfs_dir_entry* entry = (struct brfs_dir_entry*)fs_stat(path_copy);
+  if ((word)entry == -1)
+  {
+    bdos_println("Path not found");
+    send_404_response(s);
+    return;
+  }
+
+  if ((entry->flags & 0x01) == 0)
+  {
+    // File
+    serve_file(s, path);
+  }
+  else
+  {
+    // Directory
+    serve_dir(s, path);
+  }
+} 
+
+/**
+ * Handle a session on socket s
+*/
+void handle_session(word s)
+{
+  // Size of received data
+  word rsize = wiz_get_sock_reg_16(s, WIZNET_SnRX_RSR);
+
+  // Disconnect on no data
+  if (rsize == 0)
+  {
+    wiz_send_cmd(s, WIZNET_CR_DISCON);
+    return;
+  }
+
+  // Read data into buffer
+  wiz_read_recv_data(s, wiz_rbuf, rsize);
+
+  // Read rbuf for requested page
+  char path[MAX_PATH_LENGTH]; // Buffer for path name
+  parse_file_path(wiz_rbuf, path);
+
+  bdos_print(path);
+  bdos_print(" ");
+
+  serve_path(s, path);
+}
+
+/**
+ * Reinitialize the W5500
+*/
+word reinit_w5500()
+{
+  word ip_addr[4] = {192, 168, 0, WIZNET_IP};
+  word gateway_addr[4] = {192, 168, 0, 1};
+  word mac_addr[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0x24, 0x64};
+  word sub_mask[4] = {255, 255, 255, 0};
+
+  wiz_init(ip_addr, gateway_addr, mac_addr, sub_mask);
+}
+
+/**
+ * Open all sockets in TCP Server mode at port 80
+*/
+word open_all_sockets_tcp_server()
+{
+  word s;
+  for (s = 0; s < 7; s++)
+  {
+    wiz_init_socket_tcp_host(s, 80);
+  }
+}
+
+/**
+ * Main function
+*/
+int main() 
+{
+  bdos_println("FPGC Webserver v2.0");
+
+  reinit_w5500();
+  open_all_sockets_tcp_server();
+
+  // Main loop
+  while (1)
+  {
+    if (hid_checkfifo())
+    {
+      // Return on any key press
+      hid_fiforead();
+      return 'q';
+    }
+
+    // Handle sockets 0-6
+    word s_status;
+    word s;
+    for (s = 0; s < 7; s++)
+    {
+      s_status = wiz_get_sock_reg_8(s, WIZNET_SnSR);
+
+      if (s_status == WIZNET_SOCK_CLOSED)
+      {
+        // Open the socket when closed
+        // Set socket s in TCP Server mode at port 80
+        wiz_init_socket_tcp_host(s, 80);
+      }
+      else if (s_status == WIZNET_SOCK_ESTABLISHED)
+      {
+        // Handle session when a connection is established
+        handle_session(s);
+        // Afterwards, reinitialize socket
+        wiz_init_socket_tcp_host(s, 80);
+      }
+      else if (s_status == WIZNET_SOCK_LISTEN || s_status == WIZNET_SOCK_SYNSENT || s_status == WIZNET_SOCK_SYNRECV)
+      {
+        // Do nothing in these cases
+      }
+      else
+      {
+        // In other cases, reset the socket
+        // Set socket s in TCP Server mode at port 80
+        wiz_init_socket_tcp_host(s, 80);
+      }
+    }
+    delay(20);
+  }
+
+  return 'q';
+}
+
+void interrupt()
+{
+  // Handle all interrupts
+  word i = get_int_id();
+  switch(i)
+  {
+    case INTID_TIMER1:
+      timer1Value = 1;  // Notify ending of timer1
+      break;
+  }
+}