Преглед изворни кода

Added initial code for BRFS (custom RAM filesystem).

bart пре 8 месеци
родитељ
комит
d6f7dcb26d
2 измењених фајлова са 229 додато и 0 уклоњено
  1. 216 0
      BCC/userBDOS/BRFS.C
  2. 13 0
      BCC/userBDOS/LIB/STDLIB.C

+ 216 - 0
BCC/userBDOS/BRFS.C

@@ -0,0 +1,216 @@
+// Test implementation of Bart's RAM File System (BRFS)
+
+/*
+General Idea:
+- HDD for the average home user was <100MB until after 1990
+- SPI NOR Flash provides around the same amount of storage, with relatively little wear
+    - However, writes are extremely slow
+- FPGC has 64MiB RAM, which is a lot even for 64 bit addressable words
+    - 32MiB is already more than enough for the FPGC in its current form
+- Use the other 32MiB as a fully in RAM filesystem
+    - That initializes from SPI flash and writes back to Flash at a chosen time
+*/
+
+/*
+Implementation Idea:
+- Use superblock for info/addresses, no hard-coded sizes!
+  - Allows for different storage media, easier testing on tiny size, and more future proof
+*/
+
+/*
+Implementation Details:
+--------------------------------------------------
+| superblock | FAT | Data+Dir blocks (same size) |
+--------------------------------------------------
+
+16 word superblock:
+  - (1)  total blocks
+  - (1)  bytes per block
+  - (10) label [1 char per word]
+  - (1)  brfs version
+  - (3)  reserved
+
+8 word Dir entries:
+  - (4) filename.ext [4 chars per word]
+  - (1) modify date [to be implemented when RTC]
+  - (1) flags [max 32 flags, TBD]
+  - (1) 1st FAT idx
+  - (1) file size [in words, not bytes]
+*/
+
+#define word char
+
+#include "LIB/MATH.C"
+#include "LIB/SYS.C"
+#include "LIB/STDLIB.C"
+
+#define BRFS_RAM_STORAGE_ADDR 0x500000
+
+#define SUPERBLOCK_SIZE 16
+
+word *brfs_ram_storage = (word*) BRFS_RAM_STORAGE_ADDR; // RAM storage of file system
+
+// 16 words long
+struct brfs_superblock
+{
+  word total_blocks;
+  word bytes_per_block;
+  word label[10];       // 1 char per word
+  word brfs_version;
+  word reserved[3];
+};
+
+// 16 words long
+struct brfs_dir_entry
+{
+  word filename[4];       // 4 chars per word
+  word modify_date;       // TBD when RTC added to FPGC
+  word flags;
+  word fat_idx;           // idx of first FAT block
+  word filesize;          // file size in words, not bytes
+};
+
+
+// Creates hexdump like dump
+void brfs_dump_section(word* addr, word len, word linesize)
+{
+  char buf[16];
+  word i;
+  for (i = 0; i < len; i++)
+  {
+    itoah(addr[i], buf);
+    if (strlen(buf+2) == 1)
+      uprintc('0');
+    uprint(buf+2);
+
+    uprintc(' ');
+
+    // newline every linesize words
+    // also print last linesize words as chars if alphanum
+    if (i != 0 && MATH_modU(i+1, linesize) == 0)
+    {
+      uprint("  ");
+      word j;
+      for (j = i - (linesize-1); j < i+1; j++)
+      {
+        if (isalnum(addr[j]) || addr[j] == ' ')
+          uprintc(addr[j]);
+        else
+          uprintc('.');
+      }
+      uprintc('\n');
+    }
+  }
+}
+
+void brfs_dump(word* ram_addr, word fatsize, word datasize)
+{
+  // Superblock dump
+  uprintln("Superblock:");
+  brfs_dump_section(ram_addr, SUPERBLOCK_SIZE, 16);
+
+  // FAT dump
+  uprintln("\nFAT:");
+  brfs_dump_section(ram_addr+SUPERBLOCK_SIZE, fatsize, 8);
+
+  // Datablock dump
+  uprintln("\nData:");
+  brfs_dump_section(ram_addr+SUPERBLOCK_SIZE+fatsize, datasize, 16);
+
+  uprintc('\n');
+}
+
+void brfs_format(word* ram_addr, word blocks, word bytes_per_block, char* label, word full_format)
+{
+  // Create a superblock
+  struct brfs_superblock superblock;
+
+  // Initialize to 0
+  memset(&superblock, 0, sizeof(superblock));
+
+  // Set values of superblock
+  superblock.total_blocks = blocks;
+  superblock.bytes_per_block = bytes_per_block;
+  strcpy(&(superblock.label), label);
+  superblock.brfs_version = 1;
+
+  // Copy superblock to head of ram addr
+  memcpy(ram_addr, &superblock, sizeof(superblock));
+
+
+  // Create FAT
+  memset(ram_addr + SUPERBLOCK_SIZE, 0, blocks);
+
+  // Create Data section
+  if (full_format)
+  {
+    memset(ram_addr + SUPERBLOCK_SIZE + blocks, 0, blocks * bytes_per_block);
+  }
+  
+  // Create root dir entry in first block
+  struct brfs_dir_entry root_dir;
+
+  // Initialize to 0
+  memset(&root_dir, 0, sizeof(root_dir));
+
+  // Copy root dir entry to first block
+  memcpy(ram_addr + SUPERBLOCK_SIZE + blocks, &root_dir, sizeof(root_dir));
+
+  
+}
+
+
+int main() 
+{
+  // Clear UART screen:
+  uprintc(0x1B);
+  uprintc(0x5B);
+  uprintc(0x32);
+  uprintc(0x4A);
+  uprintln("------------------------");
+  uprintln("BRFS test implementation");
+  uprintln("------------------------");
+
+  word blocks = 8;
+  word bytes_per_block = 16;
+  word full_format = 1;
+
+  brfs_format(brfs_ram_storage, blocks, bytes_per_block, "Label", full_format);
+
+  brfs_dump(brfs_ram_storage, blocks, blocks*bytes_per_block);
+
+  return 'q';
+}
+
+void interrupt()
+{
+  // handle all interrupts
+  word i = getIntID();
+  switch(i)
+  {
+    case INTID_TIMER1:
+      timer1Value = 1; // notify ending of timer1
+      break;
+
+    case INTID_TIMER2:
+      break;
+
+    case INTID_UART0:
+      break;
+
+    case INTID_GPU:
+      break;
+
+    case INTID_TIMER3:
+      break;
+
+    case INTID_PS2:
+      break;
+
+    case INTID_UART1:
+      break;
+
+    case INTID_UART2:
+      break;
+  }
+}

+ 13 - 0
BCC/userBDOS/LIB/STDLIB.C

@@ -36,6 +36,19 @@ void memcpy(word* dest, word* src, word n)
   }
 }
 
+/*
+Sets n words from dest to val
+*/
+void memset(word* dest, word val, word n)
+{
+  word i;
+  for (i = 0; i < n; i++)
+  {
+    dest[i] = val;
+  }
+}
+
+
 char* memmove(char* dest, const char* src, word n)
 {
   char* from = src;