Bläddra i källkod

Added progressbar to read from SPI flash, fixed two brfs bugs, improved df command, created print program, added disablecursor option in OS space.

bart 7 månader sedan
förälder
incheckning
927283b35d
5 ändrade filer med 149 tillägg och 38 borttagningar
  1. 2 7
      BCC/BDOS/BDOS.c
  2. 36 6
      BCC/BDOS/lib/brfs.c
  3. 7 3
      BCC/BDOS/lib/gfx.c
  4. 18 22
      BCC/BDOS/lib/shell.c
  5. 86 0
      BCC/userBDOS/print.c

+ 2 - 7
BCC/BDOS/BDOS.c

@@ -109,17 +109,12 @@ word bdos_init_brfs()
   spiflash_init();
 
   // Try to read the filesystem from the SPI flash
-  GFX_PrintConsole("Reading BRFS from SPI flash...\n");
-  if (brfs_read_from_flash())
-  {
-    GFX_PrintConsole("BRFS read from flash\n");
-  }
-  else
+  GFX_PrintConsole("Reading BRFS from SPI flash\n");
+  if (!brfs_read_from_flash())
   {
     GFX_PrintConsole("Could not read BRFS from flash!\n");
     return 0;
   }
-
   return 1;
 }
 

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

@@ -558,6 +558,7 @@ word brfs_create_file(char* parent_dir_path, char* filename)
 
   // Update changed block
   brfs_changed_blocks[next_free_block >> 5] |= (1 << (next_free_block & 31));
+  brfs_changed_blocks[parent_dir_fat_idx >> 5] |= (1 << (parent_dir_fat_idx & 31));
 
   return 1;
 }
@@ -878,7 +879,7 @@ word brfs_get_fat_idx_at_cursor(word file_pointer, word cursor)
   struct brfs_superblock* superblock = (struct brfs_superblock*) brfs_ram_storage;
 
   // Loop through FAT until cursor is reached
-  while (cursor > superblock->words_per_block)
+  while (cursor >= superblock->words_per_block)
   {
     current_fat_idx = brfs_ram_storage[SUPERBLOCK_SIZE + current_fat_idx];
     if (current_fat_idx == -1)
@@ -948,7 +949,7 @@ word brfs_read(word file_pointer, word* buffer, word length)
 
         // Copy words to buffer
         memcpy(buffer, data_block_addr + (current_fat_idx * superblock->words_per_block) + MATH_modU(brfs_cursors[i], superblock->words_per_block), words_to_read);
-
+        
         // Update cursor and length
         brfs_cursors[i] += words_to_read;
         length -= words_to_read;
@@ -961,10 +962,7 @@ word brfs_read(word file_pointer, word* buffer, word length)
           uprintln("There is no next block in the file!");
           return 0;
         }
-
-        
       }
-
       return 1;
     }
   }
@@ -1399,7 +1397,39 @@ word brfs_read_from_flash()
   // Read data blocks from flash
   word* data_block_addr = brfs_ram_storage + SUPERBLOCK_SIZE + superblock->total_blocks;
   spi_flash_read_addr = (char*) SPIFLASH_MEMMAP_ADDR + (BRFS_SPIFLASH_BLOCK_ADDR >> 2);
-  memcpy(data_block_addr, spi_flash_read_addr, superblock->total_blocks * superblock->words_per_block);
+  word read_length = superblock->total_blocks * superblock->words_per_block;
+
+  // Check if read_length is a multiple of 16
+  if (read_length & 15)
+  {
+    // Read without progress bar
+    memcpy(data_block_addr, spi_flash_read_addr, read_length);
+    spiflash_init(); // Return to SPI mode
+    return 1;
+  }
+
+  
+  // Print progress bar
+  GFX_disable_cursor = 1;
+  GFX_PrintConsole("Loading blocks: ");
+  // Print emtpy block character
+  word i;
+  for (i = 0; i < 16; i++)
+  {
+    GFX_PrintcConsole(176);
+  }
+  // Set cursor back to start of progress bar
+  GFX_cursor -= 16;
+
+  // Split in 16 parts
+  word read_length_per_part = read_length >> 4;
+  for (i = 0; i < 16; i++)
+  {
+    memcpy(data_block_addr + (i * read_length_per_part), spi_flash_read_addr + (i * read_length_per_part), read_length_per_part);
+    GFX_PrintcConsole(219); // Print full block character
+  }
+  GFX_disable_cursor = 0;
+  GFX_PrintcConsole('\n');
 
   spiflash_init(); // Return to SPI mode
   return 1;

+ 7 - 3
BCC/BDOS/lib/gfx.c

@@ -13,6 +13,7 @@
 #define GFX_CURSOR_ASCII        219
 
 word GFX_cursor = 0;
+word GFX_disable_cursor = 0;
 
 // Workaround to allow for defines in asm functions
 void GFX_asmDefines()
@@ -524,9 +525,12 @@ void GFX_ScrollUp()
 // Prints cursor character at cursor
 void GFX_printCursor()
 {
-    // print character at cursor
-    word *v = (word *) GFX_WINDOW_PATTERN_ADDR;
-    *(v+GFX_cursor) = GFX_CURSOR_ASCII;
+    if (!GFX_disable_cursor)
+    {
+        // print character at cursor
+        word *v = (word *) GFX_WINDOW_PATTERN_ADDR;
+        *(v+GFX_cursor) = GFX_CURSOR_ASCII;
+    }
 }
 
 

+ 18 - 22
BCC/BDOS/lib/shell.c

@@ -277,9 +277,10 @@ void shell_process_dots(char* path)
 */
 void shell_change_directory()
 {
-  if (shell_num_tokens != 2)
+  if (shell_num_tokens == 1)
   {
-    GFX_PrintConsole("Usage: cd <path>\n");
+    // Set path to root if no argument
+    strcpy(shell_path, "/");
     return;
   }
 
@@ -387,41 +388,36 @@ void shell_show_fs_usage()
   word used_space = used_blocks * block_size;
   word free_space = free_blocks * block_size;
   word total_space = total_blocks * block_size;
+  word percentage_used_space = MATH_divU(used_space*100, total_space);
 
-  GFX_PrintConsole("Usage:\n");
-  GFX_PrintConsole("------\n");
+  GFX_PrintConsole("Usage: ");
+  GFX_PrintDecConsole(percentage_used_space);
+  GFX_PrintConsole("%\n-----------\n");
 
-  GFX_PrintConsole("Used blocks : ");
-  GFX_PrintDecConsole(used_blocks);
-  GFX_PrintConsole("/");
-  GFX_PrintDecConsole(total_blocks);
-  GFX_PrintConsole("\n");
   GFX_PrintConsole("Used space  : ");
   GFX_PrintDecConsole(MATH_divU(used_space, 1000));
   GFX_PrintConsole("/");
   GFX_PrintDecConsole(MATH_divU(total_space, 1000));
   GFX_PrintConsole(" kwords\n");
+  GFX_PrintConsole("Used blocks : ");
+  GFX_PrintDecConsole(used_blocks);
+  GFX_PrintConsole("/");
+  GFX_PrintDecConsole(total_blocks);
+  GFX_PrintConsole("\n\n");
 
-  GFX_PrintConsole("\nFree space:\n");
-  GFX_PrintConsole("-----------\n");
-
-  GFX_PrintConsole("Free blocks : ");
-  GFX_PrintDecConsole(free_blocks);
-  GFX_PrintConsole("\n");
   GFX_PrintConsole("Free space  : ");
   GFX_PrintDecConsole(MATH_divU(free_space, 1000));
   GFX_PrintConsole(" kwords\n");
+  GFX_PrintConsole("Free blocks : ");
+  GFX_PrintDecConsole(free_blocks);
+  GFX_PrintConsole("\n\n");
   
-
-  GFX_PrintConsole("\nBlocks:\n");
-  GFX_PrintConsole("-------\n");
-
-  GFX_PrintConsole("Total blocks: ");
-  GFX_PrintDecConsole(total_blocks);
-  GFX_PrintConsole("\n");
   GFX_PrintConsole("Block size  : ");
   GFX_PrintDecConsole(block_size);
   GFX_PrintConsole(" words\n");
+  GFX_PrintConsole("Total blocks: ");
+  GFX_PrintDecConsole(total_blocks);
+  GFX_PrintConsole("\n");
 }
 
 /**

+ 86 - 0
BCC/userBDOS/print.c

@@ -0,0 +1,86 @@
+#define word char
+
+#include "lib/math.c"
+#include "lib/stdlib.c"
+#include "lib/sys.c"
+#include "lib/brfs.c"
+
+#define READ_BUFFER_SIZE 64
+
+int main() 
+{
+  // Read number of arguments
+  word argc = shell_argc();
+  if (argc < 2)
+  {
+    bdos_println("Usage: print <file>");
+    return 1;
+  }
+  
+  // Read filename
+  char** args = shell_argv();
+  char* filename = args[1];
+
+  char absolute_path[MAX_PATH_LENGTH];
+  // Check if absolute path
+  if (filename[0] != '/')
+  {
+    char* cwd = fs_getcwd();
+    strcpy(absolute_path, cwd);
+    strcat(absolute_path, "/");
+    strcat(absolute_path, filename);
+  }
+  else
+  {
+    strcpy(absolute_path, filename);
+  }
+
+  // Get file size
+  struct brfs_dir_entry* entry = (struct brfs_dir_entry*)fs_stat(absolute_path);
+  if ((word)entry == -1)
+  {
+    bdos_println("File not found");
+    return 1;
+  }
+  word filesize = entry->filesize;
+
+  // Open file
+  word fd = fs_open(absolute_path);
+  if (fd == -1)
+  {
+    bdos_println("File not found");
+    return 1;
+  }
+
+
+  // Read file in chunks of READ_BUFFER_SIZE
+  word file_buffer[READ_BUFFER_SIZE + 1]; // +1 for null terminator
+  word chunk_to_read;
+
+  while (filesize > 0)
+  {
+    chunk_to_read = filesize > READ_BUFFER_SIZE ? READ_BUFFER_SIZE : filesize;
+    memset(file_buffer, 0, READ_BUFFER_SIZE + 1);
+    fs_read(fd, file_buffer, chunk_to_read);
+    file_buffer[chunk_to_read] = 0; // Null terminator
+    bdos_print(file_buffer);
+    filesize -= chunk_to_read;
+  }
+
+  // Close file
+  fs_close(fd);
+
+  return 'q';
+}
+
+void interrupt()
+{
+  // Handle all interrupts
+  word i = get_int_id();
+  switch(i)
+  {
+    case INTID_TIMER1:
+      timer1Value = 1;  // Notify ending of timer1
+      break;
+  }
+}