disk8: Initial commit
[pdp8.git] / sw / disk8 / src / directory.c
diff --git a/sw/disk8/src/directory.c b/sw/disk8/src/directory.c
new file mode 100644 (file)
index 0000000..06b1764
--- /dev/null
@@ -0,0 +1,98 @@
+/* All directory related stuff goes here. */
+
+/*!
+ *\file directory.c
+ *\brief OS/8 directory operations
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "structures.h"
+#include "directory.h"
+#include "ops.h"
+#include "logging.h"
+
+#define SUCCESS 1
+#define FAILED 0
+
+#define INST(TYPE) ((TYPE *)malloc(sizeof(TYPE)))
+#define INSTN(TYPE,NUM)(TYPE *) malloc(NUM* sizeof(TYPE))
+
+
+/*!
+ * \brief Read OS/8 directory from partition image 
+ */
+directory_t * directory_read(os8_partition_t * image){
+
+  /* Make instance */
+  directory_t * result=INST(directory_t);
+  result->entries=0;
+
+
+  os8_direntry_t * list_head=INST(os8_direntry_t);
+  os8_direntry_t * current_entry=list_head;
+  os8_direntry_t * tmp_entry;
+
+  os8_partition_header_t * header = &image->header;
+  os8_directory_segment_t * segs=header->directory;
+  int seg_no=0;
+  
+  list_head->prev=NULL; //Mark first element
+  
+  do{
+    /* Data from the segment we're working on: */
+    os8_directory_segment_t * seg=segs+seg_no;
+    int additional_info=p8_neg(seg->additional_info_neg);
+    int first_file_start=seg->first_file_start;
+    int next_segment=seg->next_segment;
+    int no_entries=p8_neg(seg->neg_entries);
+
+    DBG ("Segment %i, Entries: %i, First Block: 0%o, additional info: 0%o, Next segment: 0%o\n",seg_no,
+        no_entries,
+        first_file_start,
+        additional_info,
+        next_segment
+        );
+    
+    int offset=0;
+    char clear[10];
+    result->entries+=no_entries;
+    result->additional_info=additional_info;
+           
+    /* Pointer to current entry */
+    p8word * entry=seg->entry_data;
+    
+    int entry_no;
+    for (entry_no=0;entry_no < p8_neg(seg->neg_entries);entry_no++){
+      
+      /* Link a new entry at the end of the list */
+      current_entry->next=INST(os8_direntry_t);
+      tmp_entry=current_entry;
+      current_entry=current_entry->next;
+      current_entry->prev=tmp_entry;
+      current_entry->next=NULL;
+
+      if (entry[0]){ // No empty file!
+       int size=p8_neg(entry[4+additional_info]);
+       current_entry->size_blocks=size;
+       if (size==0) current_entry->type=FT_TENTATIVE;
+       else current_entry->type=FT_PERMANENT;
+       
+       os8_file_name_extract((os8_file_name_t *) entry , current_entry->name);
+       DBG("File: %9s  %i\n",current_entry->name,size);
+       entry += 5+additional_info;
+      } else { // Empty file
+       int size=p8_neg(entry[1]);
+       current_entry->size_blocks=size;
+       current_entry->type=FT_EMPTY;
+       DBG("File: <empty>    %i\n",size);
+       entry += 2;
+      }
+    }
+      seg_no++;
+    } while (segs[seg_no-1].next_segment);
+
+  result->entries=list_head->next;
+  free(list_head);
+  return result;
+}