From 5547e9a2ecaab06a05e5364e4a59f6227458a6b1 Mon Sep 17 00:00:00 2001 From: "ardi@ist-einmalig.de" Date: Sun, 26 Jul 2009 12:12:04 +0000 Subject: [PATCH] adds a dynamic ramdisk. Right now its not used. It can be use to save temporary files e.g. to extract of opening.bnr --- source/ramdisc/ramdisc.cpp | 198 +++++++++++++++++++++++++++++++++++++ source/ramdisc/ramdisc.h | 39 ++++++++ 2 files changed, 237 insertions(+) create mode 100644 source/ramdisc/ramdisc.cpp create mode 100644 source/ramdisc/ramdisc.h diff --git a/source/ramdisc/ramdisc.cpp b/source/ramdisc/ramdisc.cpp new file mode 100644 index 00000000..40f7d0c6 --- /dev/null +++ b/source/ramdisc/ramdisc.cpp @@ -0,0 +1,198 @@ +#include +#include "ramdisc.h" + +static inline u16 u8array_to_u16 (const u8* item, int offset) +{ + return ( item[offset] | (item[offset + 1] << 8)); +} +static inline u32 u8array_to_u32 (const u8* item, int offset) +{ + return ( item[offset] | (item[offset + 1] << 8) | (item[offset + 2] << 16) | (item[offset + 3] << 24) ); +} +static inline void u16_to_u8array (u8* item, int offset, u16 value) +{ + item[offset] = (u8) value; item[offset + 1] = (u8)(value >> 8); +} +static inline void u32_to_u8array (u8* item, int offset, u32 value) +{ + item[offset] = (u8) value; + item[offset + 1] = (u8)(value >> 8); + item[offset + 2] = (u8)(value >> 16); + item[offset + 3] = (u8)(value >> 24); +} + + +class padding +{ +public: + padding(u32 Start, u32 NumSectors) + { + start = Start; + end = Start + NumSectors; + data = new u8[NumSectors*512]; + next = 0; + } + ~padding() { delete [] data;} + + u32 start; + u32 end; + u8 *data; + padding *next; +}; + +static u32 __ramdisk_sectorsOfPadding; +static padding *__ramdisk_data_start; +static padding *__ramdisk_data_end; + +static bool __ramdisk_IsInserted(void) +{ + return __ramdisk_data_start!=NULL; +} +//forward decleration +static bool __ramdisk_WriteSectors(size_t Sector, size_t numSectors, u8 *Buffer); + +bool initRAMDisc(u32 Size, u32 Padding) +{ + if(__ramdisk_data_start) return true; // is init + + if(Size > 16*1024*1024) Size = 16*1024*1024; // maximum 16 MB + if(Size < 16*1024) Size = 16*1024; // minimum 16 MB + if(Padding > Size) Padding = Size; // Padding maximum =Disksize + if(Padding < 4*1024) Padding = 4*1024; // Padding minimum 4kB + + __ramdisk_sectorsOfPadding = Padding/512; + + __ramdisk_data_start = __ramdisk_data_end = new padding(0, __ramdisk_sectorsOfPadding); + if(!__ramdisk_data_start) return false; + + // FAT12 Formatieren + u8 sector[512] = {0, }; + sector[0x00d] = 2; /*BPB_sectorsPerCluster*/ + sector[0x00e] = 1; /*BPB_reservedSectors*/ + sector[0x010] = 1; /*BPB_numFATs*/ + u16_to_u8array (sector, 0x011, 48); /*BPB_rootEntries*/ + int num_sectors = Size/512; + u16_to_u8array (sector, 0x013, num_sectors); /*BPB_numSectorsSmall*/ + int num_clusters = (num_sectors-1-3) /2; + int sectors_per_fat = (num_clusters * 3 + 1023) /1024; + u16_to_u8array (sector, 0x016, sectors_per_fat); /*BPB_sectorsPerFAT*/ + //u32_to_u8array (sector, 0x020, Size/512); /*BPB_numSectors*/ + sector[0x036] = 'F'; + sector[0x037] = 'A'; + sector[0x038] = 'T'; + sector[0x1fe] = 0x55; + sector[0x1ff] = 0xaa; + if(!__ramdisk_WriteSectors(0, 1, sector)) + goto error; + memset(sector, 0, 512); + // clear FAT & rootDir + for(int i=1; i<= sectors_per_fat+3/*sectors_per_rootDir*/; i++) + if(!__ramdisk_WriteSectors(1, 1, sector)) + goto error; + return true; +error: + delete __ramdisk_data_start; + __ramdisk_data_start = 0; + return false; + +} + +void exitRAMDisc() +{ + while(__ramdisk_data_start) + { + padding *tmp = __ramdisk_data_start; + __ramdisk_data_start = __ramdisk_data_start->next; + delete tmp; + } +} +static u8 *__ramdisk_findSector(size_t Sector, size_t *Sectors) +{ + if(__ramdisk_data_start==NULL) return NULL; + for(padding *tmp = __ramdisk_data_start; tmp; tmp=tmp->next) + { + if(tmp->start <= Sector && tmp->end >= Sector) + { + if(Sectors) *Sectors = 1+tmp->end-Sector; + return &(tmp->data[(Sector-tmp->start)*512]); + } + } + // not found -> add padding + __ramdisk_data_end->next = new padding((Sector/__ramdisk_sectorsOfPadding)*__ramdisk_sectorsOfPadding, __ramdisk_sectorsOfPadding); + if(__ramdisk_data_end->next) + { + __ramdisk_data_end = __ramdisk_data_end->next; + return &( __ramdisk_data_end->data[(Sector-__ramdisk_data_end->start)*512]); + } + return 0; +} + +static bool __ImplizitInit = false; +static bool __ramdisk_Startup(void) +{ + if(!__ramdisk_IsInserted()) + { + // Std=8MB/64kB Padding + return (__ImplizitInit = initRAMDisc(8*1024*1024, 64 * 1024)); + } + return true; +} + +static bool __ramdisk_ReadSectors(size_t Sector, size_t numSectors, u8 *Buffer) +{ + size_t num_sectors; + while(numSectors) + { + if(u8 *buff = __ramdisk_findSector(Sector,&num_sectors)) + { + if(num_sectors > numSectors) num_sectors = numSectors; + memcpy(Buffer, buff, num_sectors * 512); + numSectors -= num_sectors; + Buffer+= num_sectors; + } + else + return false; + } + return true; +} +static bool __ramdisk_WriteSectors(size_t Sector, size_t numSectors, u8 *Buffer) +{ + size_t num_sectors; + while(numSectors) + { + if(u8 *buff = __ramdisk_findSector(Sector,&num_sectors)) + { + if(num_sectors > numSectors) num_sectors = numSectors; + memcpy(buff, Buffer, num_sectors * 512); + numSectors -= num_sectors; + Buffer+= num_sectors; + } + else + return false; + } + return true; +} +static bool __ramdisk_ClearStatus(void) +{ + return true; +} +static bool __ramdisk_Shutdown(void) +{ + if(__ImplizitInit) + { + __ImplizitInit = false; + exitRAMDisc(); + } + return true; +} + +const DISC_INTERFACE __io_ramdisk = { + DEVICE_TYPE_RAM_DISK, + FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | 0x1000, + (FN_MEDIUM_STARTUP)&__ramdisk_Startup, + (FN_MEDIUM_ISINSERTED)&__ramdisk_IsInserted, + (FN_MEDIUM_READSECTORS)&__ramdisk_ReadSectors, + (FN_MEDIUM_WRITESECTORS)&__ramdisk_WriteSectors, + (FN_MEDIUM_CLEARSTATUS)&__ramdisk_ClearStatus, + (FN_MEDIUM_SHUTDOWN)&__ramdisk_Shutdown +}; diff --git a/source/ramdisc/ramdisc.h b/source/ramdisc/ramdisc.h new file mode 100644 index 00000000..d52ec607 --- /dev/null +++ b/source/ramdisc/ramdisc.h @@ -0,0 +1,39 @@ +#ifndef __RAMDISC_H +#define __RAMDISC_H + +#include +#include + +#define DEVICE_TYPE_RAM_DISK (('R'<<24)|('A'<<16)|('M'<<8)|'D') + +extern const DISC_INTERFACE __io_ramdisk; + +/* +initRamDisc initialize a dynamic RAM-disc. +Size is the maximum disksize in a range from 16kB up to 16MB +Padding is the size of blocks to be allocate in a range from 4kB up to Disksize +The RAM-disc is formated in FAT12. +*/ +bool initRAMDisc(u32 Size, u32 Padding); +/* +exitRAMDisc destroy all datas +*/ +void exitRAMDisc(); + +/* +NOTE: +if the RAM-disc allready initialized, then initRAMDisc returns with "true" without reinitialize it with the new parameters. + +__io_ramdisk.startup() initialize a ramdisc of 8MB with a padding of 64kB + +__io_ramdisk.shutdown () will only destroy the RAM-disk, if they from __io_ramdisk.startup () was initialized + +if the ramdisc initialized from initRamDisc, then you can remount the filesystem without lost all datas + +Example: + +fatMount("RAM", &__io_ramdisk, 0, 0, 0); +... +fopen("RAM:/file", ...); +*/ +#endif /*__RAMDISC_H*/