start generalising arm kernel so that implementation specific features will not be...
[AROS.git] / tools / adflib / adf_disk.c
blobfd83a45b79333483c8d99d4201ed09576415d8f9
1 /*
2 * ADF Library. (C) 1997-1999 Laurent Clevy
4 * adf_disk.c
6 * logical disk/volume code
7 */
9 #include <limits.h>
10 #include <stdlib.h>
11 #include <string.h>
13 #include "adf_str.h"
14 #include "adf_disk.h"
15 #include "adf_raw.h"
16 #include "adf_hd.h"
17 #include "adf_bitm.h"
18 #include "adf_util.h"
19 #include "adf_nativ.h"
20 #include "adf_dump.h"
21 #include "adf_err.h"
22 #include "adf_cache.h"
24 extern struct Env adfEnv;
26 RETCODE adfInstallBootBlock(struct Volume *vol, unsigned char* code)
28 int i;
29 struct bBootBlock boot;
31 if (vol->dev->devType!=DEVTYPE_FLOPDD && vol->dev->devType!=DEVTYPE_FLOPHD)
32 return RC_ERROR;
34 if (adfReadBootBlock(vol, &boot)!=RC_OK)
35 return RC_ERROR;
37 boot.rootBlock = vol->rootBlock;
38 for(i=0; i<1024-12; i++) /* bootcode */
39 boot.data[i] = code[i+12];
41 if (adfWriteBootBlock(vol, &boot)!=RC_OK)
42 return RC_ERROR;
44 vol->bootCode = TRUE;
46 return RC_OK;
51 * isSectNumValid
54 BOOL isSectNumValid(struct Volume *vol, SECTNUM nSect)
56 return( 0<=nSect && nSect < vol->totalBlocks);
62 * adfVolumeInfo
65 void adfVolumeInfo(struct Volume *vol)
67 struct bRootBlock root;
68 char diskName[35];
69 int days,month,year;
71 if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK)
72 return;
74 memset(diskName, 0, 35);
75 memcpy(diskName, root.diskName, root.nameLen);
77 printf ("Name : %-30s\n",vol->volName);
78 printf ("Type : ");
79 switch(vol->dev->devType) {
80 case DEVTYPE_FLOPDD:
81 printf ("Floppy Double Density : 880 KBytes\n");
82 break;
83 case DEVTYPE_FLOPHD:
84 printf ("Floppy High Density : 1760 KBytes\n");
85 break;
86 case DEVTYPE_HARDDISK:
87 printf ("Hard Disk partition : %3.1f KBytes\n",
88 (vol->totalBlocks) * 512.0/1024.0);
89 break;
90 case DEVTYPE_HARDFILE:
91 printf ("HardFile : %3.1f KBytes\n",
92 (vol->totalBlocks) * 512.0/1024.0);
93 break;
94 default:
95 printf ("Unknown devType!\n");
97 printf ("Filesystem : ");
98 printf("%s ",isFFS(vol->dosType) ? "FFS" : "OFS");
99 if (isINTL(vol->dosType))
100 printf ("INTL ");
101 if (isDIRCACHE(vol->dosType))
102 printf ("DIRCACHE ");
103 putchar('\n');
105 printf("Free blocks = %ld\n", (long)adfCountFreeBlocks(vol));
106 if (vol->readOnly)
107 printf("Read only\n");
108 else
109 printf("Read/Write\n");
111 /* created */
112 adfDays2Date(root.coDays, &year, &month, &days);
113 printf ("created %d/%02d/%02d %ld:%02ld:%02ld\n",days,month,year,
114 (long)root.coMins/60,(long)root.coMins%60,(long)root.coTicks/50);
115 adfDays2Date(root.days, &year, &month, &days);
116 printf ("last access %d/%02d/%02d %ld:%02ld:%02ld, ",days,month,year,
117 (long)root.mins/60,(long)root.mins%60,(long)root.ticks/50);
118 adfDays2Date(root.cDays, &year, &month, &days);
119 printf ("%d/%02d/%02d %ld:%02ld:%02ld\n",days,month,year,
120 (long)root.cMins/60,(long)root.cMins%60,(long)root.cTicks/50);
126 * adfMount
130 struct Volume* adfMount( struct Device *dev, int nPart, BOOL readOnly )
132 struct bRootBlock root;
133 struct bBootBlock boot;
134 struct Volume* vol;
136 if (dev==NULL || nPart<nPart || nPart >= dev->nVol) {
137 (*adfEnv.eFct)("adfMount : invalid parameter(s)");
138 return NULL;
141 vol = dev->volList[nPart];
142 vol->dev = dev;
143 vol->mounted = TRUE;
145 if (adfReadBootBlock(vol, &boot)!=RC_OK) {
146 (*adfEnv.wFct)("adfMount : BootBlock invalid");
147 return NULL;
150 vol->dosType = boot.dosType[3];
151 if (isFFS(vol->dosType))
152 vol->datablockSize=512;
153 else
154 vol->datablockSize=488;
156 if (dev->readOnly /*|| isDIRCACHE(vol->dosType)*/)
157 vol->readOnly = TRUE;
158 else
159 vol->readOnly = readOnly;
161 vol->rootBlock = boot.rootBlock;
163 if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK) {
164 (*adfEnv.wFct)("adfMount : RootBlock invalid");
165 return NULL;
168 adfReadBitmap( vol, &root );
169 vol->curDirPtr = vol->rootBlock;
171 //printf("blockSize=%d\n",vol->blockSize);
173 return( vol );
179 * adfUnMount
181 * free bitmap structures
182 * free current dir
184 void adfUnMount(struct Volume *vol)
186 if (!vol) {
187 (*adfEnv.eFct)("adfUnMount : vol is null");
188 return;
191 adfFreeBitmap(vol);
193 vol->mounted = FALSE;
200 * adfCreateVol
204 struct Volume* adfCreateVol( struct Device* dev, ULONG start, ULONG len, int reserved,
205 char* volName, int dosType )
207 struct bBootBlock boot;
208 struct bRootBlock root;
209 // struct bDirCacheBlock dirc;
210 SECTNUM blkList[2];
211 struct Volume* vol;
212 int nlen;
214 if (adfEnv.useProgressBar)
215 (*adfEnv.progressBar)(0);
217 vol=(struct Volume*)malloc(sizeof(struct Volume));
218 if (!vol) {
219 (*adfEnv.eFct)("adfCreateVol : malloc vol");
220 return NULL;
223 /* It is illegal to have 0 reserved blocks */
224 if (reserved <= 0)
225 reserved = 2;
227 vol->dev = dev;
228 vol->firstBlock = (dev->heads * dev->sectors)*start;
229 vol->totalBlocks = (dev->heads * dev->sectors)*len;
230 vol->reservedBlocks = reserved;
231 vol->rootBlock = (vol->totalBlocks-1 + reserved)/2;
232 vol->curDirPtr = vol->rootBlock;
233 vol->dosType = dosType;
235 vol->readOnly = dev->readOnly;
237 vol->mounted = TRUE;
239 nlen = min( MAXNAMELEN, strlen(volName) );
240 vol->volName = (char*)malloc(nlen+1);
241 if (!vol->volName) {
242 (*adfEnv.eFct)("adfCreateVol : malloc");
243 free(vol); return NULL;
245 memcpy(vol->volName, volName, nlen);
246 vol->volName[nlen]='\0';
248 if (adfEnv.useProgressBar)
249 (*adfEnv.progressBar)(25);
251 memset(&boot, 0, sizeof(boot));
252 if (adfWriteBootBlock(vol, &boot)!=RC_OK) {
253 free(vol->volName); free(vol);
254 return NULL;
257 if (adfEnv.useProgressBar)
258 (*adfEnv.progressBar)(20);
260 if (adfCreateBitmap( vol )!=RC_OK) {
261 free(vol->volName); free(vol);
262 return NULL;
265 if (adfEnv.useProgressBar)
266 (*adfEnv.progressBar)(40);
269 /*for(i=0; i<127; i++)
270 printf("%3d %x, ",i,vol->bitmapTable[0]->map[i]);
272 if ( isDIRCACHE(dosType) )
273 adfGetFreeBlocks( vol, 1, blkList );
276 /*printf("[0]=%d [1]=%d\n",blkList[0],blkList[1]);*/
278 memset(&root, 0, sizeof(root));
280 if (strlen(volName)>MAXNAMELEN)
281 volName[MAXNAMELEN]='\0';
282 root.nameLen = strlen(volName);
283 memcpy(root.diskName,volName,root.nameLen);
284 adfTime2AmigaTime(adfGiveCurrentTime(),&(root.coDays),&(root.coMins),&(root.coTicks));
286 /* dircache block */
287 if ( isDIRCACHE(dosType) ) {
288 root.extension = 0L;
289 root.secType = ST_ROOT; /* needed by adfCreateEmptyCache() */
290 adfCreateEmptyCache(vol, (struct bEntryBlock*)&root, blkList[0]);
293 if (adfEnv.useProgressBar)
294 (*adfEnv.progressBar)(60);
296 if (adfWriteRootBlock(vol, vol->rootBlock, &root)!=RC_OK) {
297 free(vol->volName); free(vol);
298 return NULL;
301 /* fills root->bmPages[] and writes filled bitmapExtBlocks */
302 if (adfWriteNewBitmap(vol)!=RC_OK)
303 return NULL;
305 if (adfEnv.useProgressBar)
306 (*adfEnv.progressBar)(80);
308 if (adfUpdateBitmap(vol)!=RC_OK)
309 return NULL;
311 if (adfEnv.useProgressBar)
312 (*adfEnv.progressBar)(100);
313 //printf("free blocks %ld\n",adfCountFreeBlocks(vol));
315 /* will be managed by adfMount() later */
316 adfFreeBitmap(vol);
318 vol->mounted = FALSE;
320 return(vol);
324 /*-----*/
327 * adfReadBlock
329 * read logical block
331 RETCODE
332 adfReadBlock(struct Volume* vol, ULONG nSect, unsigned char* buf)
334 /* char strBuf[80];*/
335 ULONG pSect;
336 struct nativeFunctions *nFct;
337 RETCODE rc;
339 if (!vol->mounted) {
340 (*adfEnv.eFct)("the volume isn't mounted, adfReadBlock not possible");
341 return RC_ERROR;
344 if (nSect >= vol->totalBlocks)
345 (*adfEnv.wFct)("adfReadBlock : nSect out of range");
347 /* translate logical sect to physical sect */
348 pSect = nSect+vol->firstBlock;
350 if (adfEnv.useRWAccess)
351 (*adfEnv.rwhAccess)(pSect,nSect,FALSE);
353 //printf("psect=%ld nsect=%ld\n",pSect,nSect);
354 /* sprintf(strBuf,"ReadBlock : accessing logical block #%ld", nSect);
355 (*adfEnv.vFct)(strBuf);
357 //printf("pSect R =%ld\n",pSect);
358 nFct = adfEnv.nativeFct;
359 if (vol->dev->isNativeDev)
360 rc = (*nFct->adfNativeReadSector)(vol->dev, pSect, 512, buf);
361 else
362 rc = adfReadDumpSector(vol->dev, pSect, 512, buf);
363 //printf("rc=%ld\n",rc);
365 if (rc!=RC_OK) {
366 (*adfEnv.wFct)("adfReadBlock : Can't read sector");
367 return RC_ERROR;
368 } else
369 return RC_OK;
374 * adfWriteBlock
377 RETCODE adfWriteBlock(struct Volume* vol, ULONG nSect, unsigned char *buf)
379 ULONG pSect;
380 struct nativeFunctions *nFct;
381 RETCODE rc;
383 if (!vol->mounted) {
384 (*adfEnv.eFct)("the volume isn't mounted, adfWriteBlock not possible");
385 return RC_ERROR;
388 if (vol->readOnly) {
389 (*adfEnv.wFct)("adfWriteBlock : can't write block, read only volume");
390 return RC_ERROR;
393 if (nSect >= vol->totalBlocks) {
394 (*adfEnv.wFct)("adfWriteBlock : nSect out of range");
397 pSect = nSect+vol->firstBlock;
398 //printf("write nsect=%ld psect=%ld\n",nSect,pSect);
400 if (adfEnv.useRWAccess)
401 (*adfEnv.rwhAccess)(pSect,nSect,TRUE);
403 nFct = adfEnv.nativeFct;
404 if (vol->dev->isNativeDev)
405 rc = (*nFct->adfNativeWriteSector)(vol->dev, pSect, 512, buf);
406 else
407 rc = adfWriteDumpSector(vol->dev, pSect, 512, buf);
409 if (rc!=RC_OK)
410 return RC_ERROR;
411 else
412 return RC_OK;
417 /*#######################################################################################*/