From 92eee5feafd7843befc1fba6b1bbdbbb1c9a3031 Mon Sep 17 00:00:00 2001
From: germeier <germeier>
Date: Tue, 3 Sep 2002 21:20:53 +0000
Subject: first part of "design" fixes reading support changed to
 mpio_fatentry_t support for writing and deleting deactivated

---
 ChangeLog           |   9 ++
 libmpio/defs.h      |  32 ++++--
 libmpio/directory.c |  64 +++++++++--
 libmpio/directory.h |   7 +-
 libmpio/fat.c       | 275 +++++++++++++++++++++++++++++---------------
 libmpio/fat.h       |  22 ++--
 libmpio/io.c        |  84 ++++++++++++--
 libmpio/io.h        |   4 +-
 libmpio/mpio.c      | 323 +++++++++++++++-------------------------------------
 9 files changed, 456 insertions(+), 364 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 94778a4..9583933 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2002-09-03  Markus Germeier  <mager@tzi.de>
+
+	* first part of "design" fixes
+	* libmpio: 
+	  - introduced mpio_fatentry_t
+	  - reading support changed to mpio_fatentry_t
+	  - writing and deleting deactivated
+	    (this simply can't work right now)
+
 2002-09-03  Yuji Touya  <salmoon@users.sourceforge.net>
 
 	* add mkmpiodev script to create device file
diff --git a/libmpio/defs.h b/libmpio/defs.h
index 8498f22..ffd664f 100644
--- a/libmpio/defs.h
+++ b/libmpio/defs.h
@@ -1,7 +1,7 @@
 /* -*- linux-c -*- */
 
 /* 
- * $Id: defs.h,v 1.1 2002/08/28 16:10:51 salmoon Exp $
+ * $Id: defs.h,v 1.2 2002/09/03 21:20:53 germeier Exp $
  *
  * Library for USB MPIO-*
  *
@@ -156,6 +156,24 @@ typedef struct {
   mpio_smartmedia_t external;
 } mpio_t;
 
+typedef struct {
+  mpio_t *m;
+  BYTE mem;                        /* internal/external memory */
+
+  DWORD entry;                     /* number of FAT entry */
+
+  /* internal */
+  BYTE  i_fat[16];                 /* internal FAT entry */
+
+  /* external */
+  DWORD e_sector;                  /* logical startsector of cluster */
+
+  /* mapping to HW (== block address) */
+  DWORD hw_address;                /* 3 bytes block addressing + 1 byte chip */
+  
+} mpio_fatentry_t;
+
+
 /* these are copied from:
  * http://www.linuxhq.com/kernel/v2.4/doc/filesystems/vfat.txt.html
  *
@@ -165,12 +183,12 @@ typedef struct  { // Short 8.3 names
   unsigned char name[8];          // file name 
   unsigned char ext[3];           // file extension 
   unsigned char attr;             // attribute byte 
-  unsigned char lcase;		// Case for base and extension
-  unsigned char ctime_ms;		// Creation time, milliseconds
-  unsigned char ctime[2];		// Creation time
-  unsigned char cdate[2];		// Creation date
-  unsigned char adate[2];		// Last access date
-  unsigned char reserved[2];	// reserved values (ignored) 
+  unsigned char lcase;		  // Case for base and extension
+  unsigned char ctime_ms;         // Creation time, milliseconds
+  unsigned char ctime[2];         // Creation time
+  unsigned char cdate[2];         // Creation date
+  unsigned char adate[2];         // Last access date
+  unsigned char reserved[2];	  // reserved values (ignored) 
   unsigned char time[2];          // time stamp 
   unsigned char date[2];          // date stamp 
   unsigned char start[2];         // starting cluster number 
diff --git a/libmpio/directory.c b/libmpio/directory.c
index 0344c1c..10a4af0 100644
--- a/libmpio/directory.c
+++ b/libmpio/directory.c
@@ -1,6 +1,6 @@
 /* 
  *
- * $Id: directory.c,v 1.2 2002/09/03 10:22:24 germeier Exp $
+ * $Id: directory.c,v 1.3 2002/09/03 21:20:53 germeier Exp $
  *
  * Library for USB MPIO-*
  *
@@ -266,21 +266,51 @@ mpio_rootdir_clear (mpio_t *m, mpio_mem_t mem)
   mpio_smartmedia_t *sm;  
 
   if (mem == MPIO_INTERNAL_MEM) sm=&m->internal;
-  if (mem==MPIO_EXTERNAL_MEM) sm=&m->external;
+  if (mem == MPIO_EXTERNAL_MEM) sm=&m->external;
 
   memset(sm->dir, 0x00, DIR_SIZE);
 
   return 0;
 }
 
-WORD
-mpio_dentry_get_startsector(mpio_t *m, BYTE *p)
+int
+mpio_dentry_get_filesize(mpio_t *m, mpio_mem_t mem, BYTE *p)
+{
+  int s;
+  int fsize;
+  mpio_dir_entry_t *dentry;
+
+  s  = mpio_dentry_get_size(m, p);
+  s -= DIR_ENTRY_SIZE ;
+
+  dentry = (mpio_dir_entry_t *)p;
+
+  while (s != 0) {
+    dentry++;
+    s -= DIR_ENTRY_SIZE ;
+  }
+
+  fsize  = dentry->size[3];
+  fsize *= 0x100;
+  fsize += dentry->size[2];
+  fsize *= 0x100;
+  fsize += dentry->size[1];
+  fsize *= 0x100;
+  fsize += dentry->size[0];
+
+  return fsize; 
+}
+
+
+mpio_fatentry_t *
+mpio_dentry_get_startcluster(mpio_t *m, mpio_mem_t mem, BYTE *p)
 {
   int s;
-  int sektor;
+  DWORD cluster;
   mpio_dir_slot_t *dentry;
+  mpio_fatentry_t *new;
 
-  s = mpio_dentry_get_size(m, p);
+  s  = mpio_dentry_get_size(m, p);
   s -= DIR_ENTRY_SIZE ;
 
   dentry = (mpio_dir_slot_t *)p;
@@ -290,9 +320,25 @@ mpio_dentry_get_startsector(mpio_t *m, BYTE *p)
     s -= DIR_ENTRY_SIZE ;
   }
 
-  sektor = dentry->start[1] * 0x100 + dentry->start[0];
+  cluster = dentry->start[1] * 0x100 + dentry->start[0];
 
-  return sektor; 
+  if (mem == MPIO_INTERNAL_MEM) 
+    cluster = mpio_fat_internal_find_startsector(m, cluster);
+  if (cluster < 0)
+    return NULL;
+
+  new = mpio_fatentry_new(m, mem, cluster);
+
+  if (mem == MPIO_INTERNAL_MEM) 
+    { 
+      cluster *= 0x20;
+      cluster +=
+	0x01000000 * ((cluster / 0x20 / (m->internal.fat_size * SECTOR_SIZE /
+				  0x10 / m->internal.chips)) + 1);
+      new->hw_address=cluster;
+    }  
+  
+  return new; 
 }
 
 int
@@ -471,7 +517,7 @@ mpio_dentry_delete(mpio_t *m, BYTE mem, BYTE *filename)
   BYTE tmp[DIR_SIZE];
 
   if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
-  if (mem==MPIO_EXTERNAL_MEM) sm = &m->external;
+  if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
 
   start = mpio_dentry_find_name(m, mem, filename);
   
diff --git a/libmpio/directory.h b/libmpio/directory.h
index ddce24c..f1303ae 100644
--- a/libmpio/directory.h
+++ b/libmpio/directory.h
@@ -1,6 +1,6 @@
 /* 
  *
- * $Id: directory.h,v 1.1 2002/08/28 16:10:51 salmoon Exp $
+ * $Id: directory.h,v 1.2 2002/09/03 21:20:53 germeier Exp $
  *
  * Library for USB MPIO-*
  *
@@ -26,6 +26,8 @@
 #ifndef _MPIO_DIRECTORY_H_
 #define _MPIO_DIRECTORY_H_
 
+#include "fat.h"
+
 /* root directory operations */
 int     mpio_rootdir_read (mpio_t *, mpio_mem_t);
 int	mpio_rootdir_clear (mpio_t *, mpio_mem_t);
@@ -34,12 +36,13 @@ int     mpio_rootdir_format(mpio_t *, mpio_mem_t);
 /* operations on a single directory entry */
 int	mpio_dentry_get_size(mpio_t *, BYTE *);
 int	mpio_dentry_get_raw(mpio_t *, BYTE *, BYTE *, int);
-WORD    mpio_dentry_get_startsector(mpio_t *, BYTE *);
 int	mpio_dentry_put(mpio_t *, BYTE, BYTE *, int,
 			WORD, BYTE, BYTE, BYTE, BYTE, DWORD, WORD);
 BYTE *	mpio_dentry_find_name_8_3(mpio_t *, BYTE, BYTE *);
 BYTE *	mpio_dentry_find_name(mpio_t *, BYTE, BYTE *);
 int	mpio_dentry_delete(mpio_t *, BYTE, BYTE *);
+int     mpio_dentry_get_filesize(mpio_t *, mpio_mem_t, BYTE *);
+mpio_fatentry_t    *mpio_dentry_get_startcluster(mpio_t *, mpio_mem_t, BYTE *);
 
 /* helper functions */
 void    mpio_dentry_copy_from_slot(BYTE *, mpio_dir_slot_t *);
diff --git a/libmpio/fat.c b/libmpio/fat.c
index 900d75f..29a44fe 100644
--- a/libmpio/fat.c
+++ b/libmpio/fat.c
@@ -1,6 +1,6 @@
 /* 
  *
- * $Id: fat.c,v 1.2 2002/09/03 10:22:24 germeier Exp $
+ * $Id: fat.c,v 1.3 2002/09/03 21:20:53 germeier Exp $
  *
  * Library for USB MPIO-*
  *
@@ -128,6 +128,43 @@ mpio_bootblocks_read (mpio_t *m, mpio_mem_t mem)
   return 0;  
 }
 
+mpio_fatentry_t *
+mpio_fatentry_new(mpio_t *m, mpio_mem_t mem, DWORD sector)
+{
+  mpio_smartmedia_t *sm;
+  mpio_fatentry_t *new;
+  
+  new = malloc (sizeof(mpio_fatentry_t));
+  
+  if (new) 
+    {
+      new->m      = m;
+      new->mem    = mem;
+      new->entry  = sector;      
+    }  
+  
+    return new;
+}
+  
+int
+mpio_fatentry_plus_plus(mpio_fatentry_t *f)
+{
+  f->entry++;
+
+  if (f->mem == MPIO_INTERNAL_MEM) {
+    if (f->entry > f->m->internal.max_cluster)
+      return 0;    
+  }
+  
+  if (f->mem == MPIO_EXTERNAL_MEM) {
+    if (f->entry > (f->m->external.max_cluster - 2))
+      return 0;    
+  }
+  
+  return 1;
+}
+
+
 /* read "fat_size" sectors of fat into the provided buffer */
 int
 mpio_fat_read (mpio_t *m, mpio_mem_t mem)
@@ -161,14 +198,14 @@ mpio_fat_read (mpio_t *m, mpio_mem_t mem)
 }
 
 int
-mpio_fat_entry_free(mpio_t *m, mpio_mem_t mem, int entry )
+mpio_fatentry_free(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f )
 {
   int e;
-  mpio_smartmedia_t *sm;
+  mpio_smartmedia_t *sm;  
   
   if (mem == MPIO_INTERNAL_MEM) {    
     sm = &m->internal;
-    e = entry * 0x10;
+    e  = f->entry * 0x10;
 
     if((sm->fat[e+0] == 0xff) &&
        (sm->fat[e+1] == 0xff) &&
@@ -178,15 +215,15 @@ mpio_fat_entry_free(mpio_t *m, mpio_mem_t mem, int entry )
 
   if (mem == MPIO_EXTERNAL_MEM) {    
     sm = &m->internal;
-    if (mpio_fat_entry_read(m, mem, entry) == 0)
+    if (mpio_fatentry_read(m, mem, f) == 0)
       return 1;
   }
 
   return 0;
 }
 
-int
-mpio_fat_entry_read(mpio_t *m, mpio_mem_t mem, int entry )
+DWORD
+mpio_fatentry_read(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f )
 {
   mpio_smartmedia_t *sm;  
   int e;  
@@ -194,17 +231,18 @@ mpio_fat_entry_read(mpio_t *m, mpio_mem_t mem, int entry )
   
   if (mem == MPIO_INTERNAL_MEM) {    
     sm = &m->internal;
-    e = entry;    
-    e = e * 0x10 + 7;
+    e  = f->entry;    
+    e  = e * 0x10 + 7;
     if((sm->fat[e+0] == 0xff) &&
        (sm->fat[e+1] == 0xff) &&
        (sm->fat[e+2] == 0xff) &&
        (sm->fat[e+3] == 0xff))
       return 0xffffffff;
        
-    v = (sm->fat[e+1] * 0x10000 +
-	 sm->fat[e+2] * 0x100 +
-	 sm->fat[e+3]) / 0x20 + sm->fat[e+0] * 0x1000000;    
+    v = sm->fat[e+0] * 0x1000000 +
+        sm->fat[e+1] * 0x10000 +
+        sm->fat[e+2] * 0x100 + 
+        sm->fat[e+3];    
   
     return v; 
   }
@@ -213,14 +251,14 @@ mpio_fat_entry_read(mpio_t *m, mpio_mem_t mem, int entry )
 
   if (sm->size == 128) {
     /* 2 Byte per entry */
-    e = entry * 2;
+    e = f->entry * 2;
     v = sm->fat[e + 1] * 0x100 + sm->fat[e];
   } else {
     /* 1.5 Byte per entry */
     /* Nibble order: x321 */
-    e = (entry * 3 / 2);
+    e = (f->entry * 3 / 2);
 /*     printf("mager: byte (%d/%d)\n", e, e+1); */
-    if ((entry & 0x01) == 0) {
+    if ((f->entry & 0x01) == 0) {
       /* LLxH */
       /* 21x3 */
       v = (sm->fat[e + 1] & 0x0f) * 0x100 + sm->fat[e];
@@ -234,41 +272,36 @@ mpio_fat_entry_read(mpio_t *m, mpio_mem_t mem, int entry )
 }
 
 int 
-mpio_fat_entry_write(mpio_t *m, mpio_mem_t mem, int entry, WORD value)
+mpio_fatentry_write(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f, WORD value)
 {
   mpio_smartmedia_t *sm;  
   int e;
   BYTE backup;
 
-  if (mem == MPIO_INTERNAL_MEM) {    
-    sm = &m->internal;
-  }
-  
-  if (mem == MPIO_EXTERNAL_MEM) {
-    sm = &m->external;
-  }
-  if (sm->size == 128) {
-    /* 2 Byte per entry */
-    e = entry * 2;
-    sm->fat[e]   = value & 0xff;
-    sm->fat[e + 1] = (value >> 8 ) & 0xff;
-    
-  } else {
-    /* 1.5 Byte per entry */
-    e = (entry * 3 / 2);
-    if ((entry & 0x01) == 0) {
-      /* 21x3 */
-      sm->fat[e]   = value & 0xff;
-      backup       = sm->fat[e + 1] & 0xf0;
-      sm->fat[e + 1] = backup | (( value / 0x100  ) & 0x0f);
+  if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
+  if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
+
+  if (sm->size == 128) 
+    {
+      /* 2 Byte per entry */
+      e = f->entry * 2;
+      sm->fat[e]     = value & 0xff;
+      sm->fat[e + 1] = (value >> 8 ) & 0xff;      
     } else {
-      /* 1x32 */
-      sm->fat[e + 1] = (value / 0x10) & 0xff;
-      backup       = sm->fat[e] & 0x0f;
-      sm->fat[e]   = backup | ( (value * 0x10) & 0xf0 );
-    }    
-      
-  }
+      /* 1.5 Byte per entry */
+      e = (f->entry * 3 / 2);
+      if ((f->entry & 0x01) == 0) {
+	/* 21x3 */
+	sm->fat[e]     = value & 0xff;
+	backup         = sm->fat[e + 1] & 0xf0;
+	sm->fat[e + 1] = backup | (( value / 0x100  ) & 0x0f);
+      } else {
+	/* 1x32 */
+	sm->fat[e + 1] = (value / 0x10) & 0xff;
+	backup         = sm->fat[e] & 0x0f;
+	sm->fat[e]     = backup | ( (value * 0x10) & 0xf0 );
+      }      
+    }  
 
   return 0;
 }
@@ -276,17 +309,20 @@ mpio_fat_entry_write(mpio_t *m, mpio_mem_t mem, int entry, WORD value)
 int 
 mpio_fat_internal_find_startsector(mpio_t *m, BYTE start)
 {
-  int i = 0;
-  int found = 0;
+  mpio_fatentry_t *f;
   mpio_smartmedia_t *sm = &m->internal;
+  int found=-1;
 
-  while ((i < sm->max_cluster) && (!found)) {
-    if ((sm->fat[i * 0x10]  == 0xaa) &&
-	(sm->fat[i * 0x10 + 1] == start)) {
-      found = i;
+  f = mpio_fatentry_new(m, MPIO_INTERNAL_MEM, 0);
+
+  while(mpio_fatentry_plus_plus(f))
+    {
+      if ((sm->fat[f->entry * 0x10]     == 0xaa) &&
+	  (sm->fat[f->entry * 0x10 + 1] == start)) 
+	found=f->entry;
     }
-    i++;      
-  }
+
+  free(f);
 
   return found;
 }
@@ -295,65 +331,118 @@ int
 mpio_fat_free_clusters(mpio_t *m, mpio_mem_t mem)
 {
   mpio_smartmedia_t *sm;  
+  mpio_fatentry_t *f;
   int i;
   int e = 0;
   int fsize;
-  if (mem == MPIO_INTERNAL_MEM) {    
-    sm = &m->internal;
-    
-    for (i = 0; i < sm->max_cluster; i++)
-      if (mpio_fat_entry_free(m, mem, i)) e++;	
-  }
+
+  f = mpio_fatentry_new(m, mem, 0);
   
-  if (mem == MPIO_EXTERNAL_MEM) {
-    sm = &m->external;
-    fsize = sm->fat_size * SECTOR_SIZE;
+  do 
+    {
+      if (mpio_fatentry_free(m, mem, f)) e++;      
+    } while (mpio_fatentry_plus_plus(f));
 
-    if (sm->size == 128) {
-      fsize /= 2;
-    } else {
-      fsize *= 2;
-      fsize /= 3;
-    }
-    for (i = 0; i < (sm->max_cluster - 1); i++)
-      if (mpio_fat_entry_read(m, mem, i) == 0) e++;	
-  }
+  free(f);
     
   return (e * 16);
 }
 
-int  
+mpio_fatentry_t *
 mpio_fat_find_free(mpio_t *m, mpio_mem_t mem)
 {
-  mpio_smartmedia_t *sm;  
-  int i;
-  int fsize;
-  int found = 0;
+  mpio_fatentry_t *f;
 
-  if (mem == MPIO_INTERNAL_MEM) {    
-    sm = &m->internal;
-    
-    for (i = 2; ((i < sm->max_cluster) && (!found)); i++)
-      if (mpio_fat_entry_free(m, mem, i)) found = i;	
-  }
+  f = mpio_fatentry_new(m, mem, 1);
+
+  while(mpio_fatentry_plus_plus(f))
+    {
+      if (mpio_fatentry_free(m, mem, f))
+	return f;
+    }
+
+  free(f);
+
+  return NULL;
+}
+
+int              
+mpio_fatentry_next_free(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f)
+{
+  mpio_fatentry_t backup;
+
+  memcpy(&backup, f, sizeof(mpio_fatentry_t));
+
+  while(mpio_fatentry_plus_plus(f))
+    {
+      if (mpio_fatentry_free(m, mem, f))
+	return 1;
+    }
+
+  /* no free entry found, restore entry */
+  memcpy(f, &backup, sizeof(mpio_fatentry_t));
+
+  return 0;
+}
+
+int              
+mpio_fatentry_next_entry(mpio_t *m, mpio_mem_t mem, mpio_fatentry_t *f)
+{
+  mpio_smartmedia_t *sm;
+  DWORD value;
+  DWORD endvalue;
+  BYTE chip;
+
+  value    = mpio_fatentry_read(m, mem, f);
+  f->entry = value;
   
-  if (mem == MPIO_EXTERNAL_MEM) {
-    sm = &m->external;
-    fsize = sm->fat_size * SECTOR_SIZE;
+  if (mem == MPIO_INTERNAL_MEM) 
+    {
+      sm = &m->internal;      
+      f->hw_address = value;
 
-    if (sm->size == 128) {
-      fsize /= 2;
-    } else {
-      fsize *= 2;
-      fsize /= 3;
+      if (value == 0xffffffff)
+	return 0;
+
+      chip = value >> 24;
+
+      value &= 0xffffff;
+      value /= 0x20;
+      value += (chip-1) 
+	* (m->internal.fat_size * SECTOR_SIZE / 0x10 / m->internal.chips);  
+
+
+/* this is the opposite code in  mpio_dentry_get_startcluster */
+/*       cluster += */
+/* 	0x01000000 * ((cluster / 0x20 / (m->internal.fat_size * SECTOR_SIZE / */
+/* 				  0x10 / m->internal.chips)) + 1); */
+
+      
+      f->entry = value;
+      
     }
-    for (i = 2; ((i < (sm->max_cluster-1)) && (!found)); i++)
-      if (mpio_fat_entry_read(m, mem, i)==0)	found = i;	
-  }
+  
 
-  return found;
+  if (mem == MPIO_EXTERNAL_MEM) 
+    {      
+      sm    = &m->external;
+      
+      if (sm->size==128) 
+	{
+	  endvalue = 0xfff8;
+	} else {
+	  endvalue = 0xff8;
+	} 
+      
+      if (value >= endvalue)
+	return 0;
+	  
+    }  
+
+  return 1;
 }
 
+
 int
 mpio_fat_clear(mpio_t *m, mpio_mem_t mem)
 {
diff --git a/libmpio/fat.h b/libmpio/fat.h
index dc6c6d0..1afa2c4 100644
--- a/libmpio/fat.h
+++ b/libmpio/fat.h
@@ -1,6 +1,6 @@
 /* 
  *
- * $Id: fat.h,v 1.1 2002/08/28 16:10:51 salmoon Exp $
+ * $Id: fat.h,v 1.2 2002/09/03 21:20:53 germeier Exp $
  *
  * Library for USB MPIO-*
  *
@@ -28,19 +28,25 @@
 
 #include "defs.h"
 
-
 int	mpio_bootblocks_read(mpio_t *, mpio_mem_t);
 
 int	mpio_fat_read(mpio_t *, mpio_mem_t);
 int	mpio_fat_write(mpio_t *, mpio_mem_t);
 int	mpio_fat_clear(mpio_t *, mpio_mem_t);
-
-int	mpio_fat_entry_read(mpio_t *, mpio_mem_t, int);
-int	mpio_fat_entry_write(mpio_t *, mpio_mem_t, int, WORD);
-int	mpio_fat_entry_free(mpio_t *, mpio_mem_t, int);
-
 int	mpio_fat_free_clusters(mpio_t *, mpio_mem_t);
-int	mpio_fat_find_free(mpio_t *, mpio_mem_t);
+int	mpio_fat_free(mpio_t *, mpio_mem_t);
+
+mpio_fatentry_t *mpio_fatentry_new(mpio_t *, mpio_mem_t, DWORD);
+int              mpio_fatentry_plus_plus(mpio_fatentry_t *);
+
+mpio_fatentry_t *mpio_fatentry_find_free(mpio_t *, mpio_mem_t);
+int              mpio_fatentry_next_free(mpio_t *, mpio_mem_t, 
+					 mpio_fatentry_t *);
+int              mpio_fatentry_next_entry(mpio_t *, mpio_mem_t, 
+					 mpio_fatentry_t *);
+DWORD	         mpio_fatentry_read(mpio_t *, mpio_mem_t, mpio_fatentry_t *);
+int	         mpio_fatentry_write(mpio_t *, mpio_mem_t, mpio_fatentry_t *, 
+				     WORD);
 
 int	mpio_fat_internal_find_startsector(mpio_t *, BYTE);
 
diff --git a/libmpio/io.c b/libmpio/io.c
index 01af3bc..10346d6 100644
--- a/libmpio/io.c
+++ b/libmpio/io.c
@@ -2,7 +2,7 @@
 
 /* 
  *
- * $Id: io.c,v 1.2 2002/09/03 10:22:24 germeier Exp $
+ * $Id: io.c,v 1.3 2002/09/03 21:20:53 germeier Exp $
  *
  * Library for USB MPIO-*
  *
@@ -45,6 +45,56 @@
 #include "ecc.h"
 
 WORD index2blockaddress(WORD);
+int cluster2block(int mem, int sector);
+
+/*
+ * HELP!
+ *
+ * somebody explain me these values!!!
+ *
+ */
+
+int 
+cluster2block(int mem, int sector)
+{
+  int a = sector;
+
+  /* No Zone-based block management for SmartMedia below 32MB !!*/
+
+  if (mem == 32) 
+    {
+      if (sector >= 998) 
+	a += 22;
+    }  
+
+  if (mem == 64) 
+    {
+      /* I'm so large in *not* knowing! */
+      if (sector >= 89)
+	a++;
+      if (a >= 1000)
+	a += 21;    
+      if (a >= 2021)
+	a += 24;
+      if (a >= 3045)
+	a += 24;    
+      /* WHAT? */
+      if (a >= 3755)
+	a++;      
+    }
+
+  if (mem == 128) 
+    {
+      /* two blocks are already spent elsewhere */
+      /* question is: where (CIS and ??) */
+      if (sector >= 998) 
+	a += 22;
+      /* ... and then add 24 empty blocks every 1000 sectors */
+      a += ((sector - 998) / 1000 * 24);
+    }  
+  
+  return a;
+}
 
 WORD index2blockaddress(WORD ba)
 {
@@ -427,26 +477,36 @@ mpio_io_sector_write(mpio_t *m, BYTE mem, DWORD index, BYTE *input)
  * read/write of blocks
  */
 int
-mpio_io_block_read(mpio_t *m, BYTE area, DWORD index, BYTE size, BYTE *output)
+mpio_io_block_read(mpio_t *m, BYTE mem, mpio_fatentry_t *f, BYTE *output)
 {
   int i=0;
   int nwrite, nread;
-  DWORD rarea=0;
+  mpio_smartmedia_t *sm;
+  BYTE  chip=0;
+  DWORD address;
   BYTE cmdpacket[CMD_SIZE], recvbuff[BLOCK_TRANS];
 
-  if (area == MPIO_INTERNAL_MEM) 
+  if (mem == MPIO_INTERNAL_MEM) 
     {
-      rarea = index / 0x1000000;    
-      index &= 0xffffff;
+      sm = &m->internal;
+      hexdump(&f->entry, 4);
+      hexdump(&f->hw_address, 4);
+      chip    = f->hw_address / 0x1000000;    
+      address = f->hw_address & 0x0ffffff;
     }
-  if (area == MPIO_EXTERNAL_MEM) 
+  if (mem == MPIO_EXTERNAL_MEM) 
     {
-      rarea = area;
-    }
+      sm = &m->external;
+      chip    = MPIO_EXTERNAL_MEM;
+      address = cluster2block(sm->size, f->entry);
+      address *= BLOCK_SECTORS;
 
-  index *= BLOCK_SECTORS;
+      /* add offset to start of "data" area! */
+      address += (sm->dir_offset + DIR_NUM - (2 * BLOCK_SECTORS));      
+	
+    }
 
-  mpio_io_set_cmdpacket(GET_BLOCK, rarea, index, size, 0, cmdpacket);
+  mpio_io_set_cmdpacket(GET_BLOCK, chip, address, sm->size, 0, cmdpacket);
 
   debugn(5, "\n>>> MPIO\n");
   hexdump(cmdpacket, sizeof(cmdpacket));
@@ -476,7 +536,7 @@ mpio_io_block_read(mpio_t *m, BYTE area, DWORD index, BYTE size, BYTE *output)
   for (i = 0; i < BLOCK_SECTORS; i++) 
     {
       /* check ECC Area information */
-      if (area==MPIO_EXTERNAL_MEM) {      
+      if (mem==MPIO_EXTERNAL_MEM) {      
 	mpio_ecc_256_check ((recvbuff + (i * SECTOR_TRANS)),                   
 			    ((recvbuff +(i * SECTOR_TRANS) + SECTOR_SIZE +13)));
 	
diff --git a/libmpio/io.h b/libmpio/io.h
index bf0960f..0436cd1 100644
--- a/libmpio/io.h
+++ b/libmpio/io.h
@@ -2,7 +2,7 @@
 
 /* 
  *
- * $Id: io.h,v 1.2 2002/09/03 10:22:24 germeier Exp $
+ * $Id: io.h,v 1.3 2002/09/03 21:20:53 germeier Exp $
  *
  * Library for USB MPIO-*
  *
@@ -48,7 +48,7 @@ int	mpio_io_sector_read(mpio_t *, BYTE, DWORD, BYTE *);
 int	mpio_io_sector_write(mpio_t *, BYTE, DWORD, BYTE *);
 
 /* */
-int	mpio_io_block_read(mpio_t *, BYTE, DWORD, BYTE, BYTE *);
+int	mpio_io_block_read(mpio_t *, BYTE, mpio_fatentry_t *, BYTE *);
 int	mpio_io_block_write(mpio_t *, BYTE, DWORD, BYTE, BYTE *);
 int	mpio_io_block_delete(mpio_t *, BYTE, DWORD, BYTE);
 
diff --git a/libmpio/mpio.c b/libmpio/mpio.c
index c9d67a6..5b69c06 100644
--- a/libmpio/mpio.c
+++ b/libmpio/mpio.c
@@ -1,6 +1,6 @@
 /* 
  *
- * $Id: mpio.c,v 1.2 2002/09/03 10:22:24 germeier Exp $
+ * $Id: mpio.c,v 1.3 2002/09/03 21:20:53 germeier Exp $
  *
  * Library for USB MPIO-*
  *
@@ -41,7 +41,6 @@
 
 #define DSTRING 100
 
-int sector_hack(int mem, int sector);
 void mpio_init_internal(mpio_t *);
 void mpio_init_external(mpio_t *);
 
@@ -72,7 +71,7 @@ mpio_init_internal(mpio_t *m)
     sm->chips = 2;
   }
 
-  /* this probably is not needed, but anyways ... */
+  /* used for size calculations (see mpio_memory_free) */
   mpio_id2geo(sm->id, &sm->geo);
 
   /* read FAT information from spare area */
@@ -182,7 +181,8 @@ mpio_memory_free(mpio_t *m, mpio_mem_t mem, int *free)
 {
   *free=mpio_fat_free_clusters(m, mem);
   if (mem==MPIO_INTERNAL_MEM) {    
-    return (m->internal.geo.SumSector * SECTOR_SIZE / 1000);    
+    return (m->internal.geo.SumSector 
+	    * SECTOR_SIZE / 1000 * m->internal.chips);    
   }
   
   if (mem==MPIO_EXTERNAL_MEM) {
@@ -216,235 +216,91 @@ mpio_get_info(mpio_t *m, mpio_info_t *info)
   snprintf(info->firmware_date, max,    "%s.%s.%s", 
 	   m->firmware.day, m->firmware.month, m->firmware.year);
   
-  if (m->internal.chips == 1) {    
-    snprintf(info->firmware_mem_internal, max, "%3dMB (%s)", 
-	     mpio_id2mem(m->internal.id), 
-	     mpio_id2manufacturer(m->internal.manufacturer));
-  } else {
-    snprintf(info->firmware_mem_internal, max, "%3dMB (%s) - %d chips", 
-	     mpio_id2mem(m->internal.id), 
-	     mpio_id2manufacturer(m->internal.manufacturer),
-	     m->internal.chips);
-  }
-
-  snprintf(info->firmware_mem_external, max, "%3dMB (%s)", 
-	   mpio_id2mem(m->external.id), 
-	   mpio_id2manufacturer(m->external.manufacturer));
-}
-
-/* void */
-/* mpio_print_version(mpio_t *m) */
-/* { */
-/*   printf("Firmware Id:      \"%s\"\n", m->firmware.id); */
-/*   printf("Firmware Version:  %s.%s\n", m->firmware.major,  */
-/* 	 m->firmware.minor); */
-/*   printf("Firmware Date:     %s.%s.%s\n", m->firmware.day, */
-/* 	 m->firmware.month, */
-/* 	 m->firmware.year); */
-
-/*   printf("internal Memory:   %3dMB (%s)\n",  */
-/* 	 mpio_id2mem(m->internal.id),  */
-/* 	 mpio_id2manufacturer(m->internal.manufacturer)); */
-/*   if (m->external.id!=0) {     */
-/*     printf("external Memory:   %3dMB (%s)\n",  */
-/* 	   mpio_id2mem(m->external.id), */
-/* 	   mpio_id2manufacturer(m->external.manufacturer)); */
-/*   } else { */
-/*     printf("external Memory:   %3dMB (%s)\n", 0, "not available"); */
-/*   } */
-/* } */
-
-/*
- *
- * foo
- *
- */
-
-/*
- * HELP!
- *
- * somebody explain me these values!!!
- *
- */
-
-int 
-sector_hack(int mem, int sector)
-{
-  int a = sector;
-
-  /* No Zone-based block management for SmartMedia below 32MB !!*/
-
-  if (mem == 64) {
-    /* I'm so large in *not* knowing! */
-    if (sector >= 89)
-      a++;
-    if (a >= 1000)
-      a += 21;    
-    if (a >= 2021)
-      a += 24;
-    if (a >= 3045)
-      a += 24;    
-    /* WHAT? */
-    if (a >= 3755)
-      a++;
-        
-  }
-  if ((mem == 128) || (mem == 32)) {
-    /* two blocks are already spent elsewhere */
-    /* question is: where (CIS and ??) */
-    if (sector >= 998) 
-      a += 22;
-    /* ... and then add 24 empty blocks every 1000 sectors */
-    a += ((sector - 998) / 1000 * 24);
-/*     if (a>=2020) */
-/*       a+=24; */
-/*     if (a>=3044) */
-/*       a+=24; */
-/*     if (a>=4068) */
-/*       a+=24; */
-/*     if (a>=5092) */
-/*       a+=24; */
-/*     if (a>=6116) */
-/*       a+=24; */
-/*     if (a>=7140) */
-/*       a+=24; */
-  }  
+  if (m->internal.chips == 1) 
+    {    
+      snprintf(info->firmware_mem_internal, max, "%3dMB (%s)", 
+	       mpio_id2mem(m->internal.id), 
+	       mpio_id2manufacturer(m->internal.manufacturer));
+    } else {
+      snprintf(info->firmware_mem_internal, max, "%3dMB (%s) - %d chips", 
+	       mpio_id2mem(m->internal.id)*m->internal.chips, 
+	       mpio_id2manufacturer(m->internal.manufacturer),
+	       m->internal.chips);
+    }
   
-  return a;
+  if (m->internal.id)
+    {      
+      snprintf(info->firmware_mem_external, max, "%3dMB (%s)", 
+	       mpio_id2mem(m->external.id), 
+	       mpio_id2manufacturer(m->external.manufacturer));
+    } else {
+      snprintf(info->firmware_mem_external, max, "not available");
+    }
+      
 }
-  
+
 int
 mpio_file_get(mpio_t *m, mpio_mem_t mem, BYTE *filename, 
 	      BYTE (*progress_callback)(int, int))
 {
-  BYTE *p;
-  BYTE bdummy;
-  WORD wdummy;
-
   mpio_smartmedia_t *sm;
-  int data_offset;
   BYTE fname[129];
   BYTE block[BLOCK_SIZE];
-  DWORD startsector = 0, sector;
-  DWORD realsector = 0;
   int fd, towrite;
+  BYTE   *p;
+  mpio_fatentry_t *f=0;
   
   DWORD filesize, fsize;
-  DWORD fat_and;
-  DWORD fat_end; 
+
   BYTE abort = 0;
   
   /* please fix me sometime */
-  /* the system entry are kind of special ! */
+  /* the system entries are kind of special ! */
   if (strncmp("sysdum", filename, 6) == 0)
     return 0;  
 
-  if (mem == MPIO_INTERNAL_MEM) {    
-    sm = &m->internal;
-    data_offset = 0x00;
-    fat_and = 0xffffffff;
-    fat_end = 0xffffffff;
-  }
+  if (mem == MPIO_INTERNAL_MEM) sm = &m->internal;
   
-  if (mem == MPIO_EXTERNAL_MEM) {
-    sm = &m->external;
-    data_offset = sm->dir_offset + DIR_NUM - (2 * BLOCK_SECTORS);    
-    /* FAT 16 vs. FAT 12 */  
-    if (sm->size==128) {
-      fat_and = 0xffff;
-      fat_end = 0xfff8;
-    } else {
-      fat_and = 0xfff;
-      fat_end = 0xff8;
-    } 
-  }
+  if (mem == MPIO_EXTERNAL_MEM) sm = &m->external;
 
-  p = mpio_directory_open(m, mem);
-  while (p) {
-    mpio_dentry_get (m, p,
-		     fname, 128,
-		     &wdummy, &bdummy, &bdummy,
-		     &bdummy, &bdummy, &filesize);
-    fsize = filesize;
-    if ((strcmp(fname,filename) == 0) && (strcmp(filename,fname) == 0)) {
-      startsector = mpio_dentry_get_startsector(m, p);      
-      p = NULL;
-    }
-    
-    p = mpio_dentry_next(m, p);
-  }
-  
-  /* grr, of curse these are clusters not sectors */
-  /* must code while awake, must ... */
-  if (startsector) {    
-    fd = open(filename, (O_RDWR | O_CREAT), (S_IRWXU | S_IRGRP | S_IROTH));    
-    debugn(2, "startsector: %4x\n", startsector);  
-    sector = startsector;
-    if (mem == MPIO_INTERNAL_MEM) {    
-      realsector = mpio_fat_internal_find_startsector(m, sector);
-      realsector = realsector+         /* chose the right bank */  
-	(0x01000000 * ((realsector / (sm->size / 16 * 1000 / sm->chips)) + 1));
-      sector=realsector;
-      debugn(2, "startsector (real): %4x\n", sector);  
-    } else {
-      realsector=sector_hack(sm->size, sector);
-    }
-    
-    mpio_io_block_read(m, mem, realsector + (data_offset / BLOCK_SECTORS),
-		       sm->size, block);
+  /* find file */
+  p = mpio_dentry_find_name(m, mem, filename);
+  if (!p)
+      p = mpio_dentry_find_name_8_3(m, mem, filename);
 
-    if (filesize > BLOCK_SIZE) {
-      towrite = BLOCK_SIZE;
-    } else {
-      towrite = filesize;
-    }    
+  if (p)
+    f = mpio_dentry_get_startcluster(m, mem, p);      
+  
+  if (f) {    
+    filesize=fsize=mpio_dentry_get_filesize(m, mem, p);
     
-    if (write(fd, block, towrite) != towrite) {
-      debug("error writing file data\n");
-      close(fd);
-      return -1;
-    } 
+    unlink(filename);    
+    fd = open(filename, (O_RDWR | O_CREAT), (S_IRWXU | S_IRGRP | S_IROTH));    
     
-    filesize -= towrite;
-
-    debugn(5, "sector: (%6x) %4x\n", 
-	  (sector&0xffffff), mpio_fat_entry_read(m, mem, sector&0xffffff));
-
+    do
+      {
+	debugn(2, "sector: %4x\n", f->entry);	    
     
+	mpio_io_block_read(m, mem, f, block);
 
-    while((((mpio_fat_entry_read(m, mem, (sector & 0xffffff)) & fat_and)
-	    < fat_end)) && (filesize > 0) && (!abort)) {    
-	sector=mpio_fat_entry_read(m, mem, sector & 0xffffff);	
-	debugn(2,"next sector: %4x\n", sector); 
-	if (mem == MPIO_INTERNAL_MEM) {
-	  realsector = sector;
-	} else {
-	  realsector = sector_hack(sm->size, sector);
-	}
-	    
-	debugn(2," realsector: %4x\n", realsector); 
-	
-	mpio_io_block_read(m, mem,
-			   (realsector + (data_offset / BLOCK_SECTORS)),
-			   sm->size, block);
 	if (filesize > BLOCK_SIZE) {
-	  towrite=BLOCK_SIZE;
+	  towrite = BLOCK_SIZE;
 	} else {
-	  towrite=filesize;
+	  towrite = filesize;
 	}    
 	
-	if (write(fd, block, towrite)!=towrite) {
+	if (write(fd, block, towrite) != towrite) {
 	  debug("error writing file data\n");
 	  close(fd);
 	  return -1;
-	}    
-	filesize-=towrite;
+	} 
+	filesize -= towrite;
 	
 	if (progress_callback)
 	  abort=(*progress_callback)((fsize-filesize), fsize);
 
-      }
-
+      } while ((mpio_fatentry_next_entry(m, mem, f) && (filesize>0)));
+  
     close (fd);    
   } else {
     debug("unable to locate the file: %s\n", filename);
@@ -470,6 +326,8 @@ mpio_file_put(mpio_t *m, mpio_mem_t mem, BYTE *filename,
   DWORD fat_end;  
   BYTE abort=0;
   
+  debug("Support for writing files is deactivated!");
+  return 0;
 
   if (mem==MPIO_INTERNAL_MEM) {    
     sm=&m->internal;
@@ -531,7 +389,7 @@ mpio_file_put(mpio_t *m, mpio_mem_t mem, BYTE *filename,
       sector=startsector;
       debugn(2, "startsector: %d\n", startsector);
       /* evil hacks are us ;-) */
-      mpio_fat_entry_write(m, mem, startsector, fat_and);
+/*       mpio_fatentry_write(m, mem, startsector, fat_and); */
     } else {
       nextsector=mpio_fat_find_free(m, mem);
       if (!nextsector){
@@ -541,10 +399,10 @@ mpio_file_put(mpio_t *m, mpio_mem_t mem, BYTE *filename,
       }
       debugn(2, " nextsector: %d\n", nextsector);
 
-      mpio_fat_entry_write(m, mem, sector, nextsector);
+/*       mpio_fatentry_write(m, mem, sector, nextsector); */
       sector=nextsector;
       /* evil hacks are us ;-) */
-      mpio_fat_entry_write(m, mem, sector, fat_and);
+/*       mpio_fatentry_write(m, mem, sector, fat_and); */
 
     }
 
@@ -555,7 +413,7 @@ mpio_file_put(mpio_t *m, mpio_mem_t mem, BYTE *filename,
 /*       sector=realsector; */
 /*       debugn(2, "startsector (real): %4x\n", sector);   */
     } else {
-      realsector=sector_hack(sm->size, sector);
+/*       realsector=sector_hack(sm->size, sector); */
     }
 
 /*     debug("mager: %04x : %3d\n", realsector*BLOCK_SECTORS, realsector); */
@@ -651,6 +509,9 @@ mpio_file_del(mpio_t *m, mpio_mem_t mem, BYTE *filename,
   DWORD fat_and;
   DWORD fat_end;  
   BYTE abort=0;
+
+  debug("Support for deleting files is deactivated!");
+  return 0;
   
   /* please fix me sometime */
   /* the system entry are kind of special ! */
@@ -690,7 +551,7 @@ mpio_file_del(mpio_t *m, mpio_mem_t mem, BYTE *filename,
 		     &bdummy, &bdummy, &filesize);
     fsize=filesize;
     if ((strcmp(fname,filename)==0) && (strcmp(filename,fname)==0)) {
-      startsector=mpio_dentry_get_startsector(m, p);      
+      startsector=mpio_dentry_get_startcluster(m, mem, p);      
       p=NULL;
     }
     
@@ -709,7 +570,7 @@ mpio_file_del(mpio_t *m, mpio_mem_t mem, BYTE *filename,
       sector = realsector;
       debugn(2, "startsector (real): %4x\n", sector);  
     } else {
-      realsector = sector_hack(sm->size, sector);
+/*       realsector = sector_hack(sm->size, sector); */
     }
 
     mpio_io_block_delete(m, mem, (realsector * BLOCK_SECTORS) + data_offset,
@@ -723,38 +584,38 @@ mpio_file_del(mpio_t *m, mpio_mem_t mem, BYTE *filename,
     
     filesize -= towrite;
 
-    debugn(5, "sector: (%6x) %4x\n", 
-	  (sector&0xffffff), mpio_fat_entry_read(m, mem, sector&0xffffff));
-
-    while((((mpio_fat_entry_read(m, mem, (sector & 0xffffff)) & fat_and)
-	    < fat_end)) && (filesize>0) && (!abort)) {    
-	oldsector = sector;
-	sector = mpio_fat_entry_read(m, mem, sector & 0xffffff);	
-	mpio_fat_entry_write(m, mem, oldsector, 0);
-	debugn(2,"next sector: %4x\n", sector); 
-	if (mem == MPIO_INTERNAL_MEM) {    
-	  realsector = sector;
-	} else {
-	  realsector = sector_hack(sm->size, sector);
-	}
+/*     debugn(5, "sector: (%6x) %4x\n",  */
+/* 	  (sector&0xffffff), mpio_fatentry_read(m, mem, sector&0xffffff)); */
+
+/*     while((((mpio_fatentry_read(m, mem, (sector & 0xffffff)) & fat_and) */
+/* 	    < fat_end)) && (filesize>0) && (!abort)) {     */
+/* 	oldsector = sector; */
+/* 	sector = mpio_fatentry_read(m, mem, sector & 0xffffff);	 */
+/* 	mpio_fatentry_write(m, mem, oldsector, 0); */
+/* 	debugn(2,"next sector: %4x\n", sector);  */
+/* 	if (mem == MPIO_INTERNAL_MEM) {     */
+/* 	  realsector = sector; */
+/* 	} else { */
+/* 	  realsector = sector_hack(sm->size, sector); */
+/* 	} */
 	    
-	debugn(2," realsector: %4x\n", realsector); 
+/* 	debugn(2," realsector: %4x\n", realsector);  */
 	
-	mpio_io_block_delete(m, mem,
-			     ((realsector * BLOCK_SECTORS) + data_offset),
-			     sm->size);
-	if (filesize > BLOCK_SIZE) {
-	  towrite = BLOCK_SIZE;
-	} else {
-	  towrite = filesize;
-	}    
+/* 	mpio_io_block_delete(m, mem, */
+/* 			     ((realsector * BLOCK_SECTORS) + data_offset), */
+/* 			     sm->size); */
+/* 	if (filesize > BLOCK_SIZE) { */
+/* 	  towrite = BLOCK_SIZE; */
+/* 	} else { */
+/* 	  towrite = filesize; */
+/* 	}     */
 	
-	filesize -= towrite;
+/* 	filesize -= towrite; */
 	
-	if (progress_callback)
-	  abort=(*progress_callback)((fsize-filesize), fsize);
-      }
-    mpio_fat_entry_write(m, mem, sector, 0);
+/* 	if (progress_callback) */
+/* 	  abort=(*progress_callback)((fsize-filesize), fsize); */
+/*       } */
+/*     mpio_fatentry_write(m, mem, sector, 0); */
 
   } else {
     debug("unable to locate the file: %s\n", filename);
-- 
cgit v1.2.3