1 /*
2  *  ADF Library. (C) 1997-2002 Laurent Clevy
3  *
4  *  adf_hd.c
5  *
6  *  $Id$
7  *
8  *  harddisk / device code
9  *
10  *  This file is part of ADFLib.
11  *
12  *  ADFLib is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  ADFLib is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with Foobar; if not, write to the Free Software
24  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25  *
26  */
27 
28 
29 
30 #include<stdio.h>
31 #include<stdlib.h>
32 #include<string.h>
33 
34 #include"adf_str.h"
35 #include"hd_blk.h"
36 #include"adf_raw.h"
37 #include"adf_hd.h"
38 #include"adf_util.h"
39 #include"adf_disk.h"
40 #include"adf_nativ.h"
41 #include"adf_dump.h"
42 #include"adf_err.h"
43 
44 #include"defendian.h"
45 
46 extern struct Env adfEnv;
47 
48 /*
49  * adfDevType
50  *
51  * returns the type of a device
52  * only based of the field 'dev->size'
53  */
adfDevType(struct Device * dev)54 int adfDevType(struct Device* dev)
55 {
56     if( (dev->size==512*11*2*80) ||		/* BV */
57         (dev->size==512*11*2*81) ||		/* BV */
58         (dev->size==512*11*2*82) || 	/* BV */
59         (dev->size==512*11*2*83) )		/* BV */
60         return(DEVTYPE_FLOPDD);
61     else if (dev->size==512*22*2*80)
62         return(DEVTYPE_FLOPHD);
63     else if (dev->size>512*22*2*80)
64         return(DEVTYPE_HARDDISK);
65     else {
66 		(*adfEnv.eFct)("adfDevType : unknown device type");
67 		return(-1);
68 	}
69 }
70 
71 
72 /*
73  * adfDeviceInfo
74  *
75  * display information about the device and its volumes
76  * for demonstration purpose only since the output is stdout !
77  *
78  * can be used before adfCreateVol() or adfMount()
79  */
adfDeviceInfo(struct Device * dev)80 void adfDeviceInfo(struct Device *dev)
81 {
82 	int i;
83 
84 	printf("Cylinders   = %d\n",dev->cylinders);
85     printf("Heads       = %d\n",dev->heads);
86     printf("Sectors/Cyl = %d\n\n",dev->sectors);
87 	if (!dev->isNativeDev)
88         printf("Dump device\n\n");
89     else
90         printf("Real device\n\n");
91     printf("Volumes     = %d\n\n",dev->nVol);
92 /*
93     switch(dev->devType){
94     case DEVTYPE_FLOPDD:
95         printf("floppy dd\n"); break;
96     case DEVTYPE_FLOPHD:
97         printf("floppy hd\n"); break;
98     case DEVTYPE_HARDDISK:
99         printf("harddisk\n"); break;
100     case DEVTYPE_HARDFILE:
101         printf("hardfile\n"); break;
102     default:
103         printf("unknown devType!\n"); break;
104     }
105 */
106 
107     for(i=0; i<dev->nVol; i++) {
108         if (dev->volList[i]->volName)
109             printf("%2d :  %7d ->%7d, \"%s\"", i,
110 			dev->volList[i]->firstBlock,
111 			dev->volList[i]->lastBlock,
112 			dev->volList[i]->volName);
113         else
114             printf("%2d :  %7d ->%7d\n", i,
115 			dev->volList[i]->firstBlock,
116 			dev->volList[i]->lastBlock);
117         if (dev->volList[i]->mounted)
118 			printf(", mounted");
119         putchar('\n');
120     }
121 }
122 
123 
124 /*
125  * adfFreeTmpVolList
126  *
127  */
adfFreeTmpVolList(struct List * root)128 void adfFreeTmpVolList(struct List *root)
129 {
130     struct List *cell;
131     struct Volume *vol;
132 
133     cell = root;
134     while(cell!=NULL) {
135         vol = (struct Volume *)cell->content;
136         if (vol->volName!=NULL)
137 			free(vol->volName);
138         cell = cell->next;
139     }
140     freeList(root);
141 
142 }
143 
144 
145 /*
146  * adfMountHdFile
147  *
148  */
adfMountHdFile(struct Device * dev)149 RETCODE adfMountHdFile(struct Device *dev)
150 {
151     struct Volume* vol;
152     uint8_t buf[512];
153     int32_t size;
154     BOOL found;
155 
156     dev->devType = DEVTYPE_HARDFILE;
157     dev->nVol = 0;
158     dev->volList = (struct Volume**)malloc(sizeof(struct Volume*));
159     if (!dev->volList) {
160 		(*adfEnv.eFct)("adfMountHdFile : malloc");
161         return RC_ERROR;
162     }
163 
164     vol=(struct Volume*)malloc(sizeof(struct Volume));
165     if (!vol) {
166         (*adfEnv.eFct)("adfMountHdFile : malloc");
167         return RC_ERROR;
168     }
169     dev->volList[0] = vol;
170     dev->nVol++;      /* fixed by Dan, ... and by Gary */
171 
172     vol->volName=NULL;
173 
174     dev->cylinders = dev->size/512;
175     dev->heads = 1;
176     dev->sectors = 1;
177 
178     vol->firstBlock = 0;
179 
180     size = dev->size + 512-(dev->size%512);
181 /*printf("size=%ld\n",size);*/
182     vol->rootBlock = (size/512)/2;
183 /*printf("root=%ld\n",vol->rootBlock);*/
184     do {
185         adfReadDumpSector(dev, vol->rootBlock, 512, buf);
186         found = swapLong(buf)==T_HEADER && swapLong(buf+508)==ST_ROOT;
187         if (!found)
188             (vol->rootBlock)--;
189     }while (vol->rootBlock>1 && !found);
190 
191     if (vol->rootBlock==1) {
192         (*adfEnv.eFct)("adfMountHdFile : rootblock not found");
193         return RC_ERROR;
194     }
195     vol->lastBlock = vol->rootBlock*2 - 1 ;
196 
197     return RC_OK;
198 }
199 
200 
201 /*
202  * adfMountHd
203  *
204  * normal not used directly : called by adfMount()
205  *
206  * fills geometry fields and volumes list (dev->nVol and dev->volList[])
207  */
adfMountHd(struct Device * dev)208 RETCODE adfMountHd(struct Device *dev)
209 {
210     struct bRDSKblock rdsk;
211     struct bPARTblock part;
212     struct bFSHDblock fshd;
213 	struct bLSEGblock lseg;
214 	int32_t next;
215     struct List *vList, *listRoot;
216     int i;
217     struct Volume* vol;
218     int len;
219 
220     if (adfReadRDSKblock( dev, &rdsk )!=RC_OK)
221         return RC_ERROR;
222 
223     dev->cylinders = rdsk.cylinders;
224     dev->heads = rdsk.heads;
225     dev->sectors = rdsk.sectors;
226 
227     /* PART blocks */
228     listRoot = NULL;
229     next = rdsk.partitionList;
230     dev->nVol=0;
231     vList = NULL;
232     while( next!=-1 ) {
233         if (adfReadPARTblock( dev, next, &part )!=RC_OK) {
234             adfFreeTmpVolList(listRoot);
235             (*adfEnv.eFct)("adfMountHd : malloc");
236             return RC_ERROR;
237         }
238 
239         vol=(struct Volume*)malloc(sizeof(struct Volume));
240         if (!vol) {
241             adfFreeTmpVolList(listRoot);
242             (*adfEnv.eFct)("adfMountHd : malloc");
243             return RC_ERROR;
244         }
245         vol->volName=NULL;
246         dev->nVol++;
247 
248         vol->firstBlock = rdsk.cylBlocks * part.lowCyl;
249         vol->lastBlock = (part.highCyl+1)*rdsk.cylBlocks -1 ;
250         vol->rootBlock = (vol->lastBlock - vol->firstBlock+1)/2;
251         vol->blockSize = part.blockSize*4;
252 
253         len = min(31, part.nameLen);
254         vol->volName = (char*)malloc(len+1);
255         if (!vol->volName) {
256             adfFreeTmpVolList(listRoot);
257 			(*adfEnv.eFct)("adfMount : malloc");
258             return RC_ERROR;
259 		}
260         memcpy(vol->volName,part.name,len);
261         vol->volName[len] = '\0';
262 
263         vol->mounted = FALSE;
264 
265         /* stores temporaly the volumes in a linked list */
266         if (listRoot==NULL)
267             vList = listRoot = newCell(NULL, (void*)vol);
268         else
269             vList = newCell(vList, (void*)vol);
270 
271         if (vList==NULL) {
272             adfFreeTmpVolList(listRoot);
273 			(*adfEnv.eFct)("adfMount : newCell() malloc");
274             return RC_ERROR;
275         }
276 
277         next = part.next;
278     }
279 
280     /* stores the list in an array */
281     dev->volList = (struct Volume**)malloc(sizeof(struct Volume*) * dev->nVol);
282     if (!dev->volList) {
283         adfFreeTmpVolList(listRoot);
284 		(*adfEnv.eFct)("adfMount : unknown device type");
285         return RC_ERROR;
286     }
287     vList = listRoot;
288     for(i=0; i<dev->nVol; i++) {
289         dev->volList[i]=(struct Volume*)vList->content;
290         vList = vList->next;
291     }
292     freeList(listRoot);
293 
294     next = rdsk.fileSysHdrList;
295     while( next!=-1 ) {
296         if (adfReadFSHDblock( dev, next, &fshd )!=RC_OK) {
297             for(i=0;i<dev->nVol;i++) free(dev->volList[i]);
298             free(dev->volList);
299             (*adfEnv.eFct)("adfMount : adfReadFSHDblock");
300             return RC_ERROR;
301         }
302         next = fshd.next;
303     }
304 
305     next = fshd.segListBlock;
306     while( next!=-1 ) {
307         if (adfReadLSEGblock( dev, next, &lseg )!=RC_OK) {
308             (*adfEnv.wFct)("adfMount : adfReadLSEGblock");
309         }
310         next = lseg.next;
311     }
312 
313     return RC_OK;
314 }
315 
316 
317 /*
318  * adfMountFlop
319  *
320  * normaly not used directly, called directly by adfMount()
321  *
322  * use dev->devType to choose between DD and HD
323  * fills geometry and the volume list with one volume
324  */
adfMountFlop(struct Device * dev)325 RETCODE adfMountFlop(struct Device* dev)
326 {
327 	struct Volume *vol;
328 	struct bRootBlock root;
329 	char diskName[35];
330 
331     dev->cylinders = 80;
332     dev->heads = 2;
333     if (dev->devType==DEVTYPE_FLOPDD)
334         dev->sectors = 11;
335     else
336         dev->sectors = 22;
337 
338     vol=(struct Volume*)malloc(sizeof(struct Volume));
339     if (!vol) {
340 		(*adfEnv.eFct)("adfMount : malloc");
341         return RC_ERROR;
342     }
343 
344     vol->mounted = TRUE;
345     vol->firstBlock = 0;
346     vol->lastBlock =(dev->cylinders * dev->heads * dev->sectors)-1;
347     vol->rootBlock = (vol->lastBlock+1 - vol->firstBlock)/2;
348     vol->blockSize = 512;
349     vol->dev = dev;
350 
351 	if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK)
352 		return RC_ERROR;
353 	memset(diskName, 0, 35);
354 	memcpy(diskName, root.diskName, root.nameLen);
355 
356     vol->volName = strdup(diskName);
357 
358     dev->volList =(struct Volume**) malloc(sizeof(struct Volume*));
359     if (!dev->volList) {
360         free(vol);
361 		(*adfEnv.eFct)("adfMount : malloc");
362         return RC_ERROR;
363     }
364     dev->volList[0] = vol;
365     dev->nVol = 1;
366 
367 /*printf("root=%d\n",vol->rootBlock);	    */
368     return RC_OK;
369 }
370 
371 
372 /*
373  * adfMountDev
374  *
375  * mount a dump file (.adf) or a real device (uses adf_nativ.c and .h)
376  *
377  * adfInitDevice() must fill dev->size !
378  */
adfMountDev(char * filename,BOOL ro)379 struct Device* adfMountDev( char* filename, BOOL ro)
380 {
381     struct Device* dev;
382     struct nativeFunctions *nFct;
383     RETCODE rc;
384     uint8_t buf[512];
385 
386     dev = (struct Device*)malloc(sizeof(struct Device));
387     if (!dev) {
388 		(*adfEnv.eFct)("adfMountDev : malloc error");
389         return NULL;
390     }
391 
392     dev->readOnly = ro;
393 
394     /* switch between dump files and real devices */
395     nFct = adfEnv.nativeFct;
396     dev->isNativeDev = (*nFct->adfIsDevNative)(filename);
397     if (dev->isNativeDev)
398         rc = (*nFct->adfInitDevice)(dev, filename,ro);
399     else
400         rc = adfInitDumpDevice(dev,filename,ro);
401     if (rc!=RC_OK) {
402         free(dev); return(NULL);
403     }
404 
405     dev->devType = adfDevType(dev);
406 
407     switch( dev->devType ) {
408 
409     case DEVTYPE_FLOPDD:
410     case DEVTYPE_FLOPHD:
411         if (adfMountFlop(dev)!=RC_OK) {
412 	         if (dev->isNativeDev)					/* BV */
413 		         (*nFct->adfReleaseDevice)(dev);	/* BV */
414 	         else									/* BV */
415 		         adfReleaseDumpDevice(dev);     	/* BV */
416             free(dev); return NULL;
417         }
418         break;
419 
420     case DEVTYPE_HARDDISK:
421         /* to choose between hardfile or harddisk (real or dump) */
422         if (dev->isNativeDev)									/* BV ...from here*/
423             rc = (*nFct->adfNativeReadSector)(dev, 0, 512, buf);
424         else
425             rc = adfReadDumpSector(dev, 0, 512, buf);
426         if( rc!=RC_OK ) {
427 	         nFct = adfEnv.nativeFct;
428 	         if (dev->isNativeDev)
429 		         (*nFct->adfReleaseDevice)(dev);
430 	         else
431 		         adfReleaseDumpDevice(dev);
432             (*adfEnv.eFct)("adfMountDev : adfReadDumpSector failed");
433             free(dev); return NULL;
434         }
435 
436         /* a file with the first three bytes equal to 'DOS' */
437     	if (!dev->isNativeDev && strncmp("DOS",(char*)buf,3)==0) {
438             if (adfMountHdFile(dev)!=RC_OK) {
439 	            if (dev->isNativeDev)
440 		            (*nFct->adfReleaseDevice)(dev);
441 	            else
442 		            adfReleaseDumpDevice(dev);
443                 free(dev); return NULL;
444             }
445         }
446         else if (adfMountHd(dev)!=RC_OK) {
447 	         if (dev->isNativeDev)
448 		         (*nFct->adfReleaseDevice)(dev);
449 	         else
450 		         adfReleaseDumpDevice(dev);
451             free(dev); return NULL;								/* BV ...to here.*/
452         }
453 	    break;
454 
455     default:
456         (*adfEnv.eFct)("adfMountDev : unknown device type");
457 	      if (dev->isNativeDev)									/* BV */
458 		      (*nFct->adfReleaseDevice)(dev);					/* BV */
459 	      else													/* BV */
460 		      adfReleaseDumpDevice(dev);						/* BV */
461          free(dev); return NULL;								/* BV */
462     }
463 
464 	return dev;
465 }
466 
467 
468 /*
469  * adfCreateHdHeader
470  *
471  * create PARTIALLY the sectors of the header of one harddisk : can not be mounted
472  * back on a real Amiga ! It's because some device dependant values can't be guessed...
473  *
474  * do not use dev->volList[], but partList for partitions information : start and len are cylinders,
475  *  not blocks
476  * do not fill dev->volList[]
477  * called by adfCreateHd()
478  */
adfCreateHdHeader(struct Device * dev,int n,struct Partition ** partList)479 RETCODE adfCreateHdHeader(struct Device* dev, int n, struct Partition** partList )
480 {
481     int i;
482     struct bRDSKblock rdsk;
483     struct bPARTblock part;
484     struct bFSHDblock fshd;
485     struct bLSEGblock lseg;
486     SECTNUM j;
487     int len;
488 
489 
490     /* RDSK */
491 
492     memset((uint8_t*)&rdsk,0,sizeof(struct bRDSKblock));
493 
494     rdsk.rdbBlockLo = 0;
495 	rdsk.rdbBlockHi = (dev->sectors*dev->heads*2)-1;
496 	rdsk.loCylinder = 2;
497 	rdsk.hiCylinder = dev->cylinders-1;
498 	rdsk.cylBlocks = dev->sectors*dev->heads;
499 
500     rdsk.cylinders = dev->cylinders;
501 	rdsk.sectors = dev->sectors;
502 	rdsk.heads = dev->heads;
503 
504 	rdsk.badBlockList = -1;
505 	rdsk.partitionList = 1;
506 	rdsk.fileSysHdrList = 1 + dev->nVol;
507 
508     if (adfWriteRDSKblock(dev, &rdsk)!=RC_OK)
509         return RC_ERROR;
510 
511     /* PART */
512 
513     j=1;
514     for(i=0; i<dev->nVol; i++) {
515         memset(&part, 0, sizeof(struct bPARTblock));
516 
517         if (i<dev->nVol-1)
518             part.next = j+1;
519         else
520 			part.next = -1;
521 
522         len = min(MAXNAMELEN,strlen(partList[i]->volName));
523         part.nameLen = len;
524         strncpy(part.name, partList[i]->volName, len);
525 
526         part.surfaces = dev->heads;
527         part.blocksPerTrack = dev->sectors;
528 		part.lowCyl = partList[i]->startCyl;
529 		part.highCyl = partList[i]->startCyl + partList[i]->lenCyl -1;
530         strncpy(part.dosType, "DOS", 3);
531 
532         part.dosType[3] = partList[i]->volType & 0x01;
533 
534         if (adfWritePARTblock(dev, j, &part))
535             return RC_ERROR;
536         j++;
537     }
538 
539     /* FSHD */
540 
541     strncpy(fshd.dosType,"DOS",3);
542     fshd.dosType[3] = partList[0]->volType;
543 	fshd.next = -1;
544 	fshd.segListBlock = j+1;
545     if (adfWriteFSHDblock(dev, j, &fshd)!=RC_OK)
546         return RC_ERROR;
547 	j++;
548 
549 	/* LSEG */
550 	lseg.next = -1;
551     if (adfWriteLSEGblock(dev, j, &lseg)!=RC_OK)
552         return RC_ERROR;
553 
554     return RC_OK;
555 }
556 
557 
558 /*
559  * adfCreateFlop
560  *
561  * create a filesystem on a floppy device
562  * fills dev->volList[]
563  */
adfCreateFlop(struct Device * dev,char * volName,int volType)564 RETCODE adfCreateFlop(struct Device* dev, char* volName, int volType )
565 {
566     if (dev==NULL) {
567         (*adfEnv.eFct)("adfCreateFlop : dev==NULL");
568         return RC_ERROR;
569     }
570     dev->volList =(struct Volume**) malloc(sizeof(struct Volume*));
571     if (!dev->volList) {
572 		(*adfEnv.eFct)("adfCreateFlop : unknown device type");
573         return RC_ERROR;
574     }
575     dev->volList[0] = adfCreateVol( dev, 0L, 80L, volName, volType );
576     if (dev->volList[0]==NULL) {
577         free(dev->volList);
578         return RC_ERROR;
579     }
580     dev->nVol = 1;
581     dev->volList[0]->blockSize = 512;
582     if (dev->sectors==11)
583         dev->devType=DEVTYPE_FLOPDD;
584     else
585         dev->devType=DEVTYPE_FLOPHD;
586 
587     return RC_OK;
588 }
589 
590 
591 /*
592  * adfCreateHd
593  *
594  * create a filesystem one an harddisk device (partitions==volumes, and the header)
595  *
596  * fills dev->volList[]
597  *
598  */
adfCreateHd(struct Device * dev,int n,struct Partition ** partList)599 RETCODE adfCreateHd(struct Device* dev, int n, struct Partition** partList )
600 {
601     int i, j;
602 
603 /*struct Volume *vol;*/
604 
605     if (dev==NULL || partList==NULL || n<=0) {
606         (*adfEnv.eFct)("adfCreateHd : illegal parameter(s)");
607         return RC_ERROR;
608     }
609 
610     dev->volList =(struct Volume**) malloc(sizeof(struct Volume*)*n);
611     if (!dev->volList) {
612 		(*adfEnv.eFct)("adfCreateFlop : malloc");
613         return RC_ERROR;
614     }
615     for(i=0; i<n; i++) {
616         dev->volList[i] = adfCreateVol( dev,
617 					partList[i]->startCyl,
618 					partList[i]->lenCyl,
619 					partList[i]->volName,
620 					partList[i]->volType );
621         if (dev->volList[i]==NULL) {
622            for(j=0; j<i; j++) {
623                free( dev->volList[i] );
624 /* pas fini */
625            }
626            free(dev->volList);
627            (*adfEnv.eFct)("adfCreateHd : adfCreateVol() fails");
628         }
629         dev->volList[i]->blockSize = 512;
630     }
631     dev->nVol = n;
632 /*
633 vol=dev->volList[0];
634 printf("0first=%ld last=%ld root=%ld\n",vol->firstBlock,
635  vol->lastBlock, vol->rootBlock);
636 */
637 
638     if (adfCreateHdHeader(dev, n, partList )!=RC_OK)
639         return RC_ERROR;
640     return RC_OK;
641 }
642 
643 
644 /*
645  * adfUnMountDev
646  *
647  */
adfUnMountDev(struct Device * dev)648 void adfUnMountDev( struct Device* dev)
649 {
650     int i;
651     struct nativeFunctions *nFct;
652 
653 	if (dev==0)
654 	   return;
655 
656     for(i=0; i<dev->nVol; i++) {
657         free(dev->volList[i]->volName);
658         free(dev->volList[i]);
659     }
660     if (dev->nVol>0)
661         free(dev->volList);
662     dev->nVol = 0;
663 
664     nFct = adfEnv.nativeFct;
665     if (dev->isNativeDev)
666         (*nFct->adfReleaseDevice)(dev);
667     else
668         adfReleaseDumpDevice(dev);
669 
670     free(dev);
671 }
672 
673 
674 
675 /*
676  * ReadRDSKblock
677  *
678  */
679 	RETCODE
adfReadRDSKblock(struct Device * dev,struct bRDSKblock * blk)680 adfReadRDSKblock( struct Device* dev, struct bRDSKblock* blk )
681 {
682 
683     UCHAR buf[256];
684     struct nativeFunctions *nFct;
685     RETCODE rc2;
686     RETCODE rc = RC_OK;
687 
688     nFct = adfEnv.nativeFct;
689     if (dev->isNativeDev)
690         rc2 =(*nFct->adfNativeReadSector)(dev, 0, 256, buf);
691     else
692         rc2 = adfReadDumpSector(dev, 0, 256, buf);
693 
694     if (rc2!=RC_OK)
695        return(RC_ERROR);
696 
697     memcpy(blk, buf, 256);
698 #ifdef LITT_ENDIAN
699     /* big to little = 68000 to x86 */
700     swapEndian((uint8_t*)blk, SWBL_RDSK);
701 #endif
702 
703     if ( strncmp(blk->id,"RDSK",4)!=0 ) {
704         (*adfEnv.eFct)("ReadRDSKblock : RDSK id not found");
705         return RC_ERROR;
706     }
707 
708     if ( blk->size != 64 )
709         (*adfEnv.wFct)("ReadRDSKBlock : size != 64");				/* BV */
710 
711     if ( blk->checksum != adfNormalSum(buf,8,256) ) {
712          (*adfEnv.wFct)("ReadRDSKBlock : incorrect checksum");
713          /* BV FIX: Due to malicious Win98 write to sector
714          rc|=RC_BLOCKSUM;*/
715     }
716 
717     if ( blk->blockSize != 512 )
718          (*adfEnv.wFct)("ReadRDSKBlock : blockSize != 512");		/* BV */
719 
720     if ( blk->cylBlocks !=  blk->sectors*blk->heads )
721         (*adfEnv.wFct)( "ReadRDSKBlock : cylBlocks != sectors*heads");
722 
723     return rc;
724 }
725 
726 
727 /*
728  * adfWriteRDSKblock
729  *
730  */
731     RETCODE
adfWriteRDSKblock(struct Device * dev,struct bRDSKblock * rdsk)732 adfWriteRDSKblock(struct Device *dev, struct bRDSKblock* rdsk)
733 {
734     uint8_t buf[LOGICAL_BLOCK_SIZE];
735     uint32_t newSum;
736     struct nativeFunctions *nFct;
737     RETCODE rc2, rc = RC_OK;
738 
739     if (dev->readOnly) {
740         (*adfEnv.wFct)("adfWriteRDSKblock : can't write block, read only device");
741         return RC_ERROR;
742     }
743 
744     memset(buf,0,LOGICAL_BLOCK_SIZE);
745 
746     strncpy(rdsk->id,"RDSK",4);
747     rdsk->size = sizeof(struct bRDSKblock)/sizeof(int32_t);
748     rdsk->blockSize = LOGICAL_BLOCK_SIZE;
749     rdsk->badBlockList = -1;
750 
751     strncpy(rdsk->diskVendor,"ADFlib  ",8);
752     strncpy(rdsk->diskProduct,"harddisk.adf    ",16);
753     strncpy(rdsk->diskRevision,"v1.0",4);
754 
755     memcpy(buf, rdsk, sizeof(struct bRDSKblock));
756 #ifdef LITT_ENDIAN
757     swapEndian(buf, SWBL_RDSK);
758 #endif
759 
760     newSum = adfNormalSum(buf, 8, LOGICAL_BLOCK_SIZE);
761     swLong(buf+8, newSum);
762 
763     nFct = adfEnv.nativeFct;
764     if (dev->isNativeDev)
765         rc2=(*nFct->adfNativeWriteSector)(dev, 0, LOGICAL_BLOCK_SIZE, buf);
766     else
767         rc2=adfWriteDumpSector(dev, 0, LOGICAL_BLOCK_SIZE, buf);
768 
769     if (rc2!=RC_OK)
770        return RC_ERROR;
771 
772     return rc;
773 }
774 
775 
776 /*
777  * ReadPARTblock
778  *
779  */
780     RETCODE
adfReadPARTblock(struct Device * dev,int32_t nSect,struct bPARTblock * blk)781 adfReadPARTblock( struct Device* dev, int32_t nSect, struct bPARTblock* blk )
782 {
783     UCHAR buf[ sizeof(struct bPARTblock) ];
784     struct nativeFunctions *nFct;
785     RETCODE rc2, rc = RC_OK;
786 
787     nFct = adfEnv.nativeFct;
788     if (dev->isNativeDev)
789         rc2=(*nFct->adfNativeReadSector)(dev, nSect, sizeof(struct bPARTblock), buf);
790     else
791         rc2=adfReadDumpSector(dev, nSect, sizeof(struct bPARTblock), buf);
792 
793     if (rc2!=RC_OK)
794        return RC_ERROR;
795 
796     memcpy(blk, buf, sizeof(struct bPARTblock));
797 #ifdef LITT_ENDIAN
798     /* big to little = 68000 to x86 */
799     swapEndian((uint8_t*)blk, SWBL_PART);
800 #endif
801 
802     if ( strncmp(blk->id,"PART",4)!=0 ) {
803     	(*adfEnv.eFct)("ReadPARTblock : PART id not found");
804         return RC_ERROR;
805     }
806 
807     if ( blk->size != 64 )
808         (*adfEnv.wFct)("ReadPARTBlock : size != 64");
809 
810     if ( blk->blockSize!=128 ) {
811     	(*adfEnv.eFct)("ReadPARTblock : blockSize!=512, not supported (yet)");
812         return RC_ERROR;
813     }
814 
815     if ( blk->checksum != adfNormalSum(buf,8,256) )
816         (*adfEnv.wFct)( "ReadPARTBlock : incorrect checksum");
817 
818     return rc;
819 }
820 
821 
822 /*
823  * adfWritePARTblock
824  *
825  */
826     RETCODE
adfWritePARTblock(struct Device * dev,int32_t nSect,struct bPARTblock * part)827 adfWritePARTblock(struct Device *dev, int32_t nSect, struct bPARTblock* part)
828 {
829     uint8_t buf[LOGICAL_BLOCK_SIZE];
830     uint32_t newSum;
831     struct nativeFunctions *nFct;
832     RETCODE rc2, rc = RC_OK;
833 
834     if (dev->readOnly) {
835         (*adfEnv.wFct)("adfWritePARTblock : can't write block, read only device");
836         return RC_ERROR;
837     }
838 
839     memset(buf,0,LOGICAL_BLOCK_SIZE);
840 
841     strncpy(part->id,"PART",4);
842     part->size = sizeof(struct bPARTblock)/sizeof(int32_t);
843     part->blockSize = LOGICAL_BLOCK_SIZE;
844     part->vectorSize = 16;
845 	part->blockSize = 128;
846     part->sectorsPerBlock = 1;
847 	part->dosReserved = 2;
848 
849     memcpy(buf, part, sizeof(struct bPARTblock));
850 #ifdef LITT_ENDIAN
851     swapEndian(buf, SWBL_PART);
852 #endif
853 
854     newSum = adfNormalSum(buf, 8, LOGICAL_BLOCK_SIZE);
855     swLong(buf+8, newSum);
856 /*    *(int32_t*)(buf+8) = swapLong((uint8_t*)&newSum);*/
857 
858     nFct = adfEnv.nativeFct;
859     if (dev->isNativeDev)
860         rc2=(*nFct->adfNativeWriteSector)(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
861     else
862         rc2=adfWriteDumpSector(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
863     if (rc2!=RC_OK)
864         return RC_ERROR;
865 
866     return rc;
867 }
868 
869 /*
870  * ReadFSHDblock
871  *
872  */
873     RETCODE
adfReadFSHDblock(struct Device * dev,int32_t nSect,struct bFSHDblock * blk)874 adfReadFSHDblock( struct Device* dev, int32_t nSect, struct bFSHDblock* blk)
875 {
876     UCHAR buf[sizeof(struct bFSHDblock)];
877     struct nativeFunctions *nFct;
878     RETCODE rc;
879 
880     nFct = adfEnv.nativeFct;
881     if (dev->isNativeDev)
882         rc = (*nFct->adfNativeReadSector)(dev, nSect, sizeof(struct bFSHDblock), buf);
883     else
884         rc = adfReadDumpSector(dev, nSect, sizeof(struct bFSHDblock), buf);
885     if (rc!=RC_OK)
886         return RC_ERROR;
887 
888     memcpy(blk, buf, sizeof(struct bFSHDblock));
889 #ifdef LITT_ENDIAN
890     /* big to little = 68000 to x86 */
891     swapEndian((uint8_t*)blk, SWBL_FSHD);
892 #endif
893 
894     if ( strncmp(blk->id,"FSHD",4)!=0 ) {
895     	(*adfEnv.eFct)("ReadFSHDblock : FSHD id not found");
896         return RC_ERROR;
897     }
898 
899     if ( blk->size != 64 )
900          (*adfEnv.wFct)("ReadFSHDblock : size != 64");
901 
902     if ( blk->checksum != adfNormalSum(buf,8,256) )
903         (*adfEnv.wFct)( "ReadFSHDblock : incorrect checksum");
904 
905     return RC_OK;
906 }
907 
908 
909 /*
910  *  adfWriteFSHDblock
911  *
912  */
913     RETCODE
adfWriteFSHDblock(struct Device * dev,int32_t nSect,struct bFSHDblock * fshd)914 adfWriteFSHDblock(struct Device *dev, int32_t nSect, struct bFSHDblock* fshd)
915 {
916     uint8_t buf[LOGICAL_BLOCK_SIZE];
917     uint32_t newSum;
918     struct nativeFunctions *nFct;
919     RETCODE rc = RC_OK;
920 
921     if (dev->readOnly) {
922         (*adfEnv.wFct)("adfWriteFSHDblock : can't write block, read only device");
923         return RC_ERROR;
924     }
925 
926     memset(buf,0,LOGICAL_BLOCK_SIZE);
927 
928     strncpy(fshd->id,"FSHD",4);
929     fshd->size = sizeof(struct bFSHDblock)/sizeof(int32_t);
930 
931     memcpy(buf, fshd, sizeof(struct bFSHDblock));
932 #ifdef LITT_ENDIAN
933     swapEndian(buf, SWBL_FSHD);
934 #endif
935 
936     newSum = adfNormalSum(buf, 8, LOGICAL_BLOCK_SIZE);
937     swLong(buf+8, newSum);
938 /*    *(int32_t*)(buf+8) = swapLong((uint8_t*)&newSum);*/
939 
940     nFct = adfEnv.nativeFct;
941     if (dev->isNativeDev)
942         rc=(*nFct->adfNativeWriteSector)(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
943     else
944         rc=adfWriteDumpSector(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
945     if (rc!=RC_OK)
946         return RC_ERROR;
947 
948     return RC_OK;
949 }
950 
951 
952 /*
953  * ReadLSEGblock
954  *
955  */
956    RETCODE
adfReadLSEGblock(struct Device * dev,int32_t nSect,struct bLSEGblock * blk)957 adfReadLSEGblock(struct Device* dev, int32_t nSect, struct bLSEGblock* blk)
958 {
959     UCHAR buf[sizeof(struct bLSEGblock)];
960     struct nativeFunctions *nFct;
961     RETCODE rc;
962 
963     nFct = adfEnv.nativeFct;
964     if (dev->isNativeDev)
965         rc=(*nFct->adfNativeReadSector)(dev, nSect, sizeof(struct bLSEGblock), buf);
966     else
967         rc=adfReadDumpSector(dev, nSect, sizeof(struct bLSEGblock), buf);
968     if (rc!=RC_OK)
969         return RC_ERROR;
970 
971     memcpy(blk, buf, sizeof(struct bLSEGblock));
972 #ifdef LITT_ENDIAN
973     /* big to little = 68000 to x86 */
974     swapEndian((uint8_t*)blk, SWBL_LSEG);
975 #endif
976 
977     if ( strncmp(blk->id,"LSEG",4)!=0 ) {
978     	(*adfEnv.eFct)("ReadLSEGblock : LSEG id not found");
979         return RC_ERROR;
980     }
981 
982     if ( blk->checksum != adfNormalSum(buf,8,sizeof(struct bLSEGblock)) )
983         (*adfEnv.wFct)("ReadLSEGBlock : incorrect checksum");
984 
985     if ( blk->next!=-1 && blk->size != 128 )
986         (*adfEnv.wFct)("ReadLSEGBlock : size != 128");
987 
988     return RC_OK;
989 }
990 
991 
992 /*
993  * adfWriteLSEGblock
994  *
995  */
996     RETCODE
adfWriteLSEGblock(struct Device * dev,int32_t nSect,struct bLSEGblock * lseg)997 adfWriteLSEGblock(struct Device *dev, int32_t nSect, struct bLSEGblock* lseg)
998 {
999     uint8_t buf[LOGICAL_BLOCK_SIZE];
1000     uint32_t newSum;
1001     struct nativeFunctions *nFct;
1002     RETCODE rc;
1003 
1004     if (dev->readOnly) {
1005         (*adfEnv.wFct)("adfWriteLSEGblock : can't write block, read only device");
1006         return RC_ERROR;
1007     }
1008 
1009     memset(buf,0,LOGICAL_BLOCK_SIZE);
1010 
1011     strncpy(lseg->id,"LSEG",4);
1012     lseg->size = sizeof(struct bLSEGblock)/sizeof(int32_t);
1013 
1014     memcpy(buf, lseg, sizeof(struct bLSEGblock));
1015 #ifdef LITT_ENDIAN
1016     swapEndian(buf, SWBL_LSEG);
1017 #endif
1018 
1019     newSum = adfNormalSum(buf, 8, LOGICAL_BLOCK_SIZE);
1020     swLong(buf+8,newSum);
1021 /*    *(int32_t*)(buf+8) = swapLong((uint8_t*)&newSum);*/
1022 
1023     nFct = adfEnv.nativeFct;
1024     if (dev->isNativeDev)
1025         rc=(*nFct->adfNativeWriteSector)(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
1026     else
1027         rc=adfWriteDumpSector(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
1028 
1029     if (rc!=RC_OK)
1030         return RC_ERROR;
1031 
1032     return RC_OK;
1033 }
1034 
1035 /*##########################################################################*/
1036