Added "support" for the 64 bit data structures of EHCI in appendix B, in case the...
[cake.git] / tools / adflib / adf_hd.c
blob88e2b211f46b1dfd99269f5bb429d34226f67f3c
1 /*
2 * ADF Library. (C) 1997-1998 Laurent Clevy
4 * adf_hd.c
6 */
10 #include<stdio.h>
11 #include<stdlib.h>
12 #include<string.h>
14 #include"adf_str.h"
15 #include"hd_blk.h"
16 #include"adf_raw.h"
17 #include"adf_hd.h"
18 #include"adf_util.h"
19 #include"adf_disk.h"
20 #include"adf_nativ.h"
21 #include"adf_dump.h"
22 #include"adf_err.h"
24 #include"defendian.h"
26 extern struct Env adfEnv;
29 * adfDevType
31 * returns the type of a device
32 * only based of the field 'dev->size'
34 int adfDevType(struct Device* dev)
36 if (dev->size==512*11*2*80)
37 return(DEVTYPE_FLOPDD);
38 else if (dev->size==512*22*2*80)
39 return(DEVTYPE_FLOPHD);
40 else if (dev->size>512*22*2*80)
41 return(DEVTYPE_HARDDISK);
42 else {
43 (*adfEnv.eFct)("adfDevType : unknown device type");
44 return(-1);
50 * adfDeviceInfo
52 * display information about the device and its volumes
53 * for demonstration purpose only since the output is stdout !
55 * can be used before adfCreateVol() or adfMount()
57 void adfDeviceInfo(struct Device *dev)
59 int i;
61 printf("Cylinders = %ld\n",dev->cylinders);
62 printf("Heads = %ld\n",dev->heads);
63 printf("Sectors/Cyl = %ld\n\n",dev->sectors);
64 if (!dev->isNativeDev)
65 printf("Dump device\n\n");
66 else
67 printf("Real device\n\n");
68 printf("Volumes = %d\n\n",dev->nVol);
70 switch(dev->devType){
71 case DEVTYPE_FLOPDD:
72 printf("floppy dd\n"); break;
73 case DEVTYPE_FLOPHD:
74 printf("floppy hd\n"); break;
75 case DEVTYPE_HARDDISK:
76 printf("harddisk\n"); break;
77 case DEVTYPE_HARDFILE:
78 printf("hardfile\n"); break;
79 default:
80 printf("unknown devType!\n"); break;
84 for(i=0; i<dev->nVol; i++) {
85 if (dev->volList[i]->volName)
86 printf("%2d : %7ld ->%7ld, \"%s\"", i,
87 dev->volList[i]->firstBlock,
88 dev->volList[i]->lastBlock,
89 dev->volList[i]->volName);
90 else
91 printf("%2d : %7ld ->%7ld\n", i,
92 dev->volList[i]->firstBlock,
93 dev->volList[i]->lastBlock);
94 if (dev->volList[i]->mounted)
95 printf(", mounted");
96 putchar('\n');
102 * adfFreeTmpVolList
105 void adfFreeTmpVolList(struct List *root)
107 struct List *cell;
108 struct Volume *vol;
110 cell = root;
111 while(cell!=NULL) {
112 vol = (struct Volume *)cell->content;
113 if (vol->volName!=NULL)
114 free(vol->volName);
115 cell = cell->next;
117 freeList(root);
123 * adfMountHdFile
126 RETCODE adfMountHdFile(struct Device *dev)
128 struct Volume* vol;
129 unsigned char buf[512];
130 long size;
131 BOOL found;
133 dev->devType = DEVTYPE_HARDFILE;
134 dev->nVol = 0;
135 dev->volList = (struct Volume**)malloc(sizeof(struct Volume*));
136 if (!dev->volList) {
137 (*adfEnv.eFct)("adfMountHdFile : malloc");
138 return RC_ERROR;
141 vol=(struct Volume*)malloc(sizeof(struct Volume));
142 if (!vol) {
143 (*adfEnv.eFct)("adfMountHdFile : malloc");
144 return RC_ERROR;
146 dev->volList[0] = vol;
147 dev->nVol++; /* fixed by Dan, ... and by Gary */
149 vol->volName=NULL;
151 dev->cylinders = dev->size/512;
152 dev->heads = 1;
153 dev->sectors = 1;
155 vol->firstBlock = 0;
157 size = dev->size + 512-(dev->size%512);
158 //printf("size=%ld\n",size);
159 vol->rootBlock = ((size/512)-1+2)/2;
160 //printf("root=%ld\n",vol->rootBlock);
161 do {
162 adfReadDumpSector(dev, vol->rootBlock, 512, buf);
163 found = swapLong(buf)==T_HEADER && swapLong(buf+508)==ST_ROOT;
164 if (!found)
165 (vol->rootBlock)--;
166 }while (vol->rootBlock>1 && !found);
168 if (vol->rootBlock==1) {
169 (*adfEnv.eFct)("adfMountHdFile : rootblock not found");
170 return RC_ERROR;
172 vol->lastBlock = vol->rootBlock*2 - 1 ;
174 return RC_OK;
179 * adfMountHd
181 * normal not used directly : called by adfMount()
183 * fills geometry fields and volumes list (dev->nVol and dev->volList[])
185 RETCODE adfMountHd(struct Device *dev)
187 struct bRDSKblock rdsk;
188 struct bPARTblock part;
189 struct bFSHDblock fshd;
190 struct bLSEGblock lseg;
191 long next;
192 struct List *vList, *listRoot;
193 int i;
194 struct Volume* vol;
195 int len;
197 if (adfReadRDSKblock( dev, &rdsk )!=RC_OK)
198 return RC_ERROR;
200 dev->cylinders = rdsk.cylinders;
201 dev->heads = rdsk.heads;
202 dev->sectors = rdsk.sectors;
204 /* PART blocks */
205 listRoot = NULL;
206 next = rdsk.partitionList;
207 dev->nVol=0;
208 vList = NULL;
209 while( next!=-1 ) {
210 if (adfReadPARTblock( dev, next, &part )!=RC_OK) {
211 adfFreeTmpVolList(listRoot);
212 (*adfEnv.eFct)("adfMountHd : malloc");
213 return RC_ERROR;
216 vol=(struct Volume*)malloc(sizeof(struct Volume));
217 if (!vol) {
218 adfFreeTmpVolList(listRoot);
219 (*adfEnv.eFct)("adfMountHd : malloc");
220 return RC_ERROR;
222 vol->volName=NULL;
223 dev->nVol++;
225 vol->firstBlock = rdsk.cylBlocks * part.lowCyl;
226 vol->lastBlock = (part.highCyl+1)*rdsk.cylBlocks -1 ;
227 vol->rootBlock = (vol->lastBlock - vol->firstBlock+1)/2;
228 vol->blockSize = part.blockSize*4;
230 len = min(31, part.nameLen);
231 vol->volName = (char*)malloc(len+1);
232 if (!vol->volName) {
233 adfFreeTmpVolList(listRoot);
234 (*adfEnv.eFct)("adfMount : malloc");
235 return RC_ERROR;
237 memcpy(vol->volName,part.name,len);
238 vol->volName[len] = '\0';
240 vol->mounted = FALSE;
242 /* stores temporaly the volumes in a linked list */
243 if (listRoot==NULL)
244 vList = listRoot = newCell(NULL, (void*)vol);
245 else
246 vList = newCell(vList, (void*)vol);
248 if (vList==NULL) {
249 adfFreeTmpVolList(listRoot);
250 (*adfEnv.eFct)("adfMount : newCell() malloc");
251 return RC_ERROR;
254 next = part.next;
257 /* stores the list in an array */
258 dev->volList = (struct Volume**)malloc(sizeof(struct Volume*) * dev->nVol);
259 if (!dev->volList) {
260 adfFreeTmpVolList(listRoot);
261 (*adfEnv.eFct)("adfMount : unknown device type");
262 return RC_ERROR;
264 vList = listRoot;
265 for(i=0; i<dev->nVol; i++) {
266 dev->volList[i]=(struct Volume*)vList->content;
267 vList = vList->next;
269 freeList(listRoot);
271 next = rdsk.fileSysHdrList;
272 while( next!=-1 ) {
273 if (adfReadFSHDblock( dev, next, &fshd )!=RC_OK) {
274 for(i=0;i<dev->nVol;i++) free(dev->volList[i]);
275 free(dev->volList);
276 (*adfEnv.eFct)("adfMount : adfReadFSHDblock");
277 return RC_ERROR;
279 next = fshd.next;
282 next = fshd.segListBlock;
283 while( next!=-1 ) {
284 if (adfReadLSEGblock( dev, next, &lseg )!=RC_OK) {
285 (*adfEnv.wFct)("adfMount : adfReadLSEGblock");
287 next = lseg.next;
290 return RC_OK;
295 * adfMountFlop
297 * normaly not used directly, called directly by adfMount()
299 * use dev->devType to choose between DD and HD
300 * fills geometry and the volume list with one volume
302 RETCODE adfMountFlop(struct Device* dev)
304 struct Volume *vol;
305 struct bRootBlock root;
306 char diskName[35];
308 dev->cylinders = 80;
309 dev->heads = 2;
310 if (dev->devType==DEVTYPE_FLOPDD)
311 dev->sectors = 11;
312 else
313 dev->sectors = 22;
315 vol=(struct Volume*)malloc(sizeof(struct Volume));
316 if (!vol) {
317 (*adfEnv.eFct)("adfMount : malloc");
318 return RC_ERROR;
321 vol->mounted = TRUE;
322 vol->firstBlock = 0;
323 vol->lastBlock =(dev->cylinders * dev->heads * dev->sectors)-1;
324 vol->rootBlock = (vol->lastBlock+1 - vol->firstBlock)/2;
325 vol->blockSize = 512;
326 vol->dev = dev;
328 if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK)
329 return RC_ERROR;
330 memset(diskName, 0, 35);
331 memcpy(diskName, root.diskName, root.nameLen);
333 vol->volName = strdup(diskName);
335 dev->volList =(struct Volume**) malloc(sizeof(struct Volume*));
336 if (!dev->volList) {
337 free(vol);
338 (*adfEnv.eFct)("adfMount : malloc");
339 return RC_ERROR;
341 dev->volList[0] = vol;
342 dev->nVol = 1;
344 /*printf("root=%d\n",vol->rootBlock); */
345 return RC_OK;
350 * adfMountDev
352 * mount a dump file (.adf) or a real device (uses adf_nativ.c and .h)
354 * adfInitDevice() must fill dev->size !
356 struct Device* adfMountDev( char* filename, BOOL ro)
358 struct Device* dev;
359 struct nativeFunctions *nFct;
360 RETCODE rc;
361 unsigned char buf[512];
363 dev = (struct Device*)malloc(sizeof(struct Device));
364 if (!dev) {
365 (*adfEnv.eFct)("adfMountDev : malloc error");
366 return NULL;
369 dev->readOnly = ro;
371 /* switch between dump files and real devices */
372 nFct = adfEnv.nativeFct;
373 dev->isNativeDev = (*nFct->adfIsDevNative)(filename);
374 if (dev->isNativeDev)
375 rc = (*nFct->adfInitDevice)(dev, filename,ro);
376 else
377 rc = adfInitDumpDevice(dev,filename,ro);
378 if (rc!=RC_OK) {
379 free(dev); return(NULL);
382 dev->devType = adfDevType(dev);
384 switch( dev->devType ) {
386 case DEVTYPE_FLOPDD:
387 case DEVTYPE_FLOPHD:
388 if (adfMountFlop(dev)!=RC_OK) {
389 free(dev); return NULL;
391 break;
393 case DEVTYPE_HARDDISK:
394 /* to choose between hardfile or harddisk (real or dump) */
395 if (adfReadDumpSector(dev, 0, 512, buf)!=RC_OK) {
396 (*adfEnv.eFct)("adfMountDev : adfReadDumpSector failed");
397 free(dev); return NULL;
400 /* a file with the first three bytes equal to 'DOS' */
401 if (!dev->isNativeDev && strncmp("DOS",buf,3)==0) {
402 if (adfMountHdFile(dev)!=RC_OK) {
403 free(dev); return NULL;
406 else if (adfMountHd(dev)!=RC_OK) {
407 free(dev); return NULL;
409 break;
411 default:
412 (*adfEnv.eFct)("adfMountDev : unknown device type");
415 return dev;
420 * adfCreateHdHeader
422 * create PARTIALLY the sectors of the header of one harddisk : can not be mounted
423 * back on a real Amiga ! It's because some device dependant values can't be guessed...
425 * do not use dev->volList[], but partList for partitions information : start and len are cylinders,
426 * not blocks
427 * do not fill dev->volList[]
428 * called by adfCreateHd()
430 RETCODE adfCreateHdHeader(struct Device* dev, int n, struct Partition** partList )
432 int i;
433 struct bRDSKblock rdsk;
434 struct bPARTblock part;
435 struct bFSHDblock fshd;
436 struct bLSEGblock lseg;
437 SECTNUM j;
438 int len;
441 /* RDSK */
443 memset((unsigned char*)&rdsk,0,sizeof(struct bRDSKblock));
445 rdsk.rdbBlockLo = 0;
446 rdsk.rdbBlockHi = (dev->sectors*dev->heads*2)-1;
447 rdsk.loCylinder = 2;
448 rdsk.hiCylinder = dev->cylinders-1;
449 rdsk.cylBlocks = dev->sectors*dev->heads;
451 rdsk.cylinders = dev->cylinders;
452 rdsk.sectors = dev->sectors;
453 rdsk.heads = dev->heads;
455 rdsk.badBlockList = -1;
456 rdsk.partitionList = 1;
457 rdsk.fileSysHdrList = 1 + dev->nVol;
459 if (adfWriteRDSKblock(dev, &rdsk)!=RC_OK)
460 return RC_ERROR;
462 /* PART */
464 j=1;
465 for(i=0; i<dev->nVol; i++) {
466 memset(&part, 0, sizeof(struct bPARTblock));
468 if (i<dev->nVol-1)
469 part.next = j+1;
470 else
471 part.next = -1;
473 len = min(MAXNAMELEN,strlen(partList[i]->volName));
474 part.nameLen = len;
475 strncpy(part.name, partList[i]->volName, len);
477 part.surfaces = dev->heads;
478 part.blocksPerTrack = dev->sectors;
479 part.lowCyl = partList[i]->startCyl;
480 part.highCyl = partList[i]->startCyl + partList[i]->lenCyl -1;
481 strncpy(part.dosType, "DOS", 3);
483 part.dosType[3] = partList[i]->volType & 0x01;
485 if (adfWritePARTblock(dev, j, &part))
486 return RC_ERROR;
487 j++;
490 /* FSHD */
492 strncpy(fshd.dosType,"DOS",3);
493 fshd.dosType[3] = partList[0]->volType;
494 fshd.next = -1;
495 fshd.segListBlock = j+1;
496 if (adfWriteFSHDblock(dev, j, &fshd)!=RC_OK)
497 return RC_ERROR;
498 j++;
500 /* LSEG */
501 lseg.next = -1;
502 if (adfWriteLSEGblock(dev, j, &lseg)!=RC_OK)
503 return RC_ERROR;
505 return RC_OK;
510 * adfCreateFlop
512 * create a filesystem on a floppy device
513 * fills dev->volList[]
515 RETCODE adfCreateFlop(struct Device* dev, char* volName, int volType )
517 if (dev==NULL) {
518 (*adfEnv.eFct)("adfCreateFlop : dev==NULL");
519 return RC_ERROR;
521 dev->volList =(struct Volume**) malloc(sizeof(struct Volume*));
522 if (!dev->volList) {
523 (*adfEnv.eFct)("adfCreateFlop : unknown device type");
524 return RC_ERROR;
526 dev->volList[0] = adfCreateVol( dev, 0L, 80L, volName, volType );
527 if (dev->volList[0]==NULL) {
528 free(dev->volList);
529 return RC_ERROR;
531 dev->nVol = 1;
532 dev->volList[0]->blockSize = 512;
533 if (dev->sectors==11)
534 dev->devType=DEVTYPE_FLOPDD;
535 else
536 dev->devType=DEVTYPE_FLOPHD;
538 return RC_OK;
543 * adfCreateHd
545 * create a filesystem one an harddisk device (partitions==volumes, and the header)
547 * fills dev->volList[]
550 RETCODE adfCreateHd(struct Device* dev, int n, struct Partition** partList )
552 int i, j;
554 //struct Volume *vol;
556 if (dev==NULL || partList==NULL || n<=0) {
557 (*adfEnv.eFct)("adfCreateHd : illegal parameter(s)");
558 return RC_ERROR;
561 dev->volList =(struct Volume**) malloc(sizeof(struct Volume*)*n);
562 if (!dev->volList) {
563 (*adfEnv.eFct)("adfCreateFlop : malloc");
564 return RC_ERROR;
566 for(i=0; i<n; i++) {
567 dev->volList[i] = adfCreateVol( dev,
568 partList[i]->startCyl,
569 partList[i]->lenCyl,
570 partList[i]->volName,
571 partList[i]->volType );
572 if (dev->volList[i]==NULL) {
573 for(j=0; j<i; j++) {
574 free( dev->volList[i] );
575 /* pas fini */
577 free(dev->volList);
578 (*adfEnv.eFct)("adfCreateHd : adfCreateVol() fails");
580 dev->volList[i]->blockSize = 512;
582 dev->nVol = n;
584 vol=dev->volList[0];
585 printf("0first=%ld last=%ld root=%ld\n",vol->firstBlock,
586 vol->lastBlock, vol->rootBlock);
589 if (adfCreateHdHeader(dev, n, partList )!=RC_OK)
590 return RC_ERROR;
591 return RC_OK;
596 * adfUnMountDev
599 void adfUnMountDev( struct Device* dev)
601 int i;
602 struct nativeFunctions *nFct;
604 if (dev==0)
605 return;
607 for(i=0; i<dev->nVol; i++) {
608 free(dev->volList[i]->volName);
609 free(dev->volList[i]);
611 if (dev->nVol>0)
612 free(dev->volList);
613 dev->nVol = 0;
615 nFct = adfEnv.nativeFct;
616 if (dev->isNativeDev)
617 (*nFct->adfReleaseDevice)(dev);
618 else
619 adfReleaseDumpDevice(dev);
621 free(dev);
627 * ReadRDSKblock
630 RETCODE
631 adfReadRDSKblock( struct Device* dev, struct bRDSKblock* blk )
634 UCHAR buf[256];
635 struct nativeFunctions *nFct;
636 RETCODE rc2;
637 RETCODE rc = RC_OK;
639 nFct = adfEnv.nativeFct;
640 if (dev->isNativeDev)
641 rc2 =(*nFct->adfNativeReadSector)(dev, 0, 256, buf);
642 else
643 rc2 = adfReadDumpSector(dev, 0, 256, buf);
645 if (rc2!=RC_OK)
646 return(RC_ERROR);
648 memcpy(blk, buf, 256);
649 #ifdef LITT_ENDIAN
650 /* big to little = 68000 to x86 */
651 swapEndian((unsigned char*)blk, SWBL_RDSK);
652 #endif
654 if ( strncmp(blk->id,"RDSK",4)!=0 ) {
655 (*adfEnv.eFct)("ReadRDSKblock : RDSK id not found");
656 return RC_ERROR;
659 if ( blk->size != 64 )
660 (*adfEnv.wFct)("ReadRDSKBlock : size != 64\n");
662 if ( blk->checksum != adfNormalSum(buf,8,256) ) {
663 (*adfEnv.wFct)("ReadRDSKBlock : incorrect checksum\n");
664 rc|=RC_BLOCKSUM;
667 if ( blk->blockSize != 512 )
668 (*adfEnv.wFct)("ReadRDSKBlock : blockSize != 512\n");
670 if ( blk->cylBlocks != blk->sectors*blk->heads )
671 (*adfEnv.wFct)( "ReadRDSKBlock : cylBlocks != sectors*heads");
673 return rc;
678 * adfWriteRDSKblock
681 RETCODE
682 adfWriteRDSKblock(struct Device *dev, struct bRDSKblock* rdsk)
684 unsigned char buf[LOGICAL_BLOCK_SIZE];
685 unsigned long newSum;
686 struct nativeFunctions *nFct;
687 RETCODE rc2, rc = RC_OK;
689 if (dev->readOnly) {
690 (*adfEnv.wFct)("adfWriteRDSKblock : can't write block, read only device");
691 return RC_ERROR;
694 memset(buf,0,LOGICAL_BLOCK_SIZE);
696 strncpy(rdsk->id,"RDSK",4);
697 rdsk->size = sizeof(struct bRDSKblock)/sizeof(long);
698 rdsk->blockSize = LOGICAL_BLOCK_SIZE;
699 rdsk->badBlockList = -1;
701 strncpy(rdsk->diskVendor,"ADFlib ",8);
702 strncpy(rdsk->diskProduct,"harddisk.adf ",16);
703 strncpy(rdsk->diskRevision,"v1.0",4);
705 memcpy(buf, rdsk, sizeof(struct bRDSKblock));
706 #ifdef LITT_ENDIAN
707 swapEndian(buf, SWBL_RDSK);
708 #endif
710 newSum = adfNormalSum(buf, 8, LOGICAL_BLOCK_SIZE);
711 swLong(buf+8, newSum);
713 nFct = adfEnv.nativeFct;
714 if (dev->isNativeDev)
715 rc2=(*nFct->adfNativeWriteSector)(dev, 0, LOGICAL_BLOCK_SIZE, buf);
716 else
717 rc2=adfWriteDumpSector(dev, 0, LOGICAL_BLOCK_SIZE, buf);
719 if (rc2!=RC_OK)
720 return RC_ERROR;
722 return rc;
727 * ReadPARTblock
730 RETCODE
731 adfReadPARTblock( struct Device* dev, long nSect, struct bPARTblock* blk )
733 UCHAR buf[ sizeof(struct bPARTblock) ];
734 struct nativeFunctions *nFct;
735 RETCODE rc2, rc = RC_OK;
737 nFct = adfEnv.nativeFct;
738 if (dev->isNativeDev)
739 rc2=(*nFct->adfNativeReadSector)(dev, nSect, sizeof(struct bPARTblock), buf);
740 else
741 rc2=adfReadDumpSector(dev, nSect, sizeof(struct bPARTblock), buf);
743 if (rc2!=RC_OK)
744 return RC_ERROR;
746 memcpy(blk, buf, sizeof(struct bPARTblock));
747 #ifdef LITT_ENDIAN
748 /* big to little = 68000 to x86 */
749 swapEndian((unsigned char*)blk, SWBL_PART);
750 #endif
752 if ( strncmp(blk->id,"PART",4)!=0 ) {
753 (*adfEnv.eFct)("ReadPARTblock : PART id not found");
754 return RC_ERROR;
757 if ( blk->size != 64 )
758 (*adfEnv.wFct)("ReadPARTBlock : size != 64");
760 if ( blk->blockSize!=128 ) {
761 (*adfEnv.eFct)("ReadPARTblock : blockSize!=512, not supported (yet)");
762 return RC_ERROR;
765 if ( blk->checksum != adfNormalSum(buf,8,256) )
766 (*adfEnv.wFct)( "ReadPARTBlock : incorrect checksum");
768 return rc;
773 * adfWritePARTblock
776 RETCODE
777 adfWritePARTblock(struct Device *dev, long nSect, struct bPARTblock* part)
779 unsigned char buf[LOGICAL_BLOCK_SIZE];
780 unsigned long newSum;
781 struct nativeFunctions *nFct;
782 RETCODE rc2, rc = RC_OK;
784 if (dev->readOnly) {
785 (*adfEnv.wFct)("adfWritePARTblock : can't write block, read only device");
786 return RC_ERROR;
789 memset(buf,0,LOGICAL_BLOCK_SIZE);
791 strncpy(part->id,"PART",4);
792 part->size = sizeof(struct bPARTblock)/sizeof(long);
793 part->blockSize = LOGICAL_BLOCK_SIZE;
794 part->vectorSize = 16;
795 part->blockSize = 128;
796 part->sectorsPerBlock = 1;
797 part->dosReserved = 2;
799 memcpy(buf, part, sizeof(struct bPARTblock));
800 #ifdef LITT_ENDIAN
801 swapEndian(buf, SWBL_PART);
802 #endif
804 newSum = adfNormalSum(buf, 8, LOGICAL_BLOCK_SIZE);
805 swLong(buf+8, newSum);
806 // *(long*)(buf+8) = swapLong((unsigned char*)&newSum);
808 nFct = adfEnv.nativeFct;
809 if (dev->isNativeDev)
810 rc2=(*nFct->adfNativeWriteSector)(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
811 else
812 rc2=adfWriteDumpSector(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
813 if (rc2!=RC_OK)
814 return RC_ERROR;
816 return rc;
820 * ReadFSHDblock
823 RETCODE
824 adfReadFSHDblock( struct Device* dev, long nSect, struct bFSHDblock* blk)
826 UCHAR buf[sizeof(struct bFSHDblock)];
827 struct nativeFunctions *nFct;
828 RETCODE rc;
830 nFct = adfEnv.nativeFct;
831 if (dev->isNativeDev)
832 rc = (*nFct->adfNativeReadSector)(dev, nSect, sizeof(struct bFSHDblock), buf);
833 else
834 rc = adfReadDumpSector(dev, nSect, sizeof(struct bFSHDblock), buf);
835 if (rc!=RC_OK)
836 return RC_ERROR;
838 memcpy(blk, buf, sizeof(struct bFSHDblock));
839 #ifdef LITT_ENDIAN
840 /* big to little = 68000 to x86 */
841 swapEndian((unsigned char*)blk, SWBL_FSHD);
842 #endif
844 if ( strncmp(blk->id,"FSHD",4)!=0 ) {
845 (*adfEnv.eFct)("ReadFSHDblock : FSHD id not found");
846 return RC_ERROR;
849 if ( blk->size != 64 )
850 (*adfEnv.wFct)("ReadFSHDblock : size != 64");
852 if ( blk->checksum != adfNormalSum(buf,8,256) )
853 (*adfEnv.wFct)( "ReadFSHDblock : incorrect checksum");
855 return RC_OK;
860 * adfWriteFSHDblock
863 RETCODE
864 adfWriteFSHDblock(struct Device *dev, long nSect, struct bFSHDblock* fshd)
866 unsigned char buf[LOGICAL_BLOCK_SIZE];
867 unsigned long newSum;
868 struct nativeFunctions *nFct;
869 RETCODE rc = RC_OK;
871 if (dev->readOnly) {
872 (*adfEnv.wFct)("adfWriteFSHDblock : can't write block, read only device");
873 return RC_ERROR;
876 memset(buf,0,LOGICAL_BLOCK_SIZE);
878 strncpy(fshd->id,"FSHD",4);
879 fshd->size = sizeof(struct bFSHDblock)/sizeof(long);
881 memcpy(buf, fshd, sizeof(struct bFSHDblock));
882 #ifdef LITT_ENDIAN
883 swapEndian(buf, SWBL_FSHD);
884 #endif
886 newSum = adfNormalSum(buf, 8, LOGICAL_BLOCK_SIZE);
887 swLong(buf+8, newSum);
888 // *(long*)(buf+8) = swapLong((unsigned char*)&newSum);
890 nFct = adfEnv.nativeFct;
891 if (dev->isNativeDev)
892 rc=(*nFct->adfNativeWriteSector)(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
893 else
894 rc=adfWriteDumpSector(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
895 if (rc!=RC_OK)
896 return RC_ERROR;
898 return RC_OK;
903 * ReadLSEGblock
906 RETCODE
907 adfReadLSEGblock(struct Device* dev, long nSect, struct bLSEGblock* blk)
909 UCHAR buf[sizeof(struct bLSEGblock)];
910 struct nativeFunctions *nFct;
911 RETCODE rc;
913 nFct = adfEnv.nativeFct;
914 if (dev->isNativeDev)
915 rc=(*nFct->adfNativeReadSector)(dev, nSect, sizeof(struct bLSEGblock), buf);
916 else
917 rc=adfReadDumpSector(dev, nSect, sizeof(struct bLSEGblock), buf);
918 if (rc!=RC_OK)
919 return RC_ERROR;
921 memcpy(blk, buf, sizeof(struct bLSEGblock));
922 #ifdef LITT_ENDIAN
923 /* big to little = 68000 to x86 */
924 swapEndian((unsigned char*)blk, SWBL_LSEG);
925 #endif
927 if ( strncmp(blk->id,"LSEG",4)!=0 ) {
928 (*adfEnv.eFct)("ReadLSEGblock : LSEG id not found");
929 return RC_ERROR;
932 if ( blk->checksum != adfNormalSum(buf,8,sizeof(struct bLSEGblock)) )
933 (*adfEnv.wFct)("ReadLSEGBlock : incorrect checksum");
935 if ( blk->next!=-1 && blk->size != 128 )
936 (*adfEnv.wFct)("ReadLSEGBlock : size != 128");
938 return RC_OK;
943 * adfWriteLSEGblock
946 RETCODE
947 adfWriteLSEGblock(struct Device *dev, long nSect, struct bLSEGblock* lseg)
949 unsigned char buf[LOGICAL_BLOCK_SIZE];
950 unsigned long newSum;
951 struct nativeFunctions *nFct;
952 RETCODE rc;
954 if (dev->readOnly) {
955 (*adfEnv.wFct)("adfWriteLSEGblock : can't write block, read only device");
956 return RC_ERROR;
959 memset(buf,0,LOGICAL_BLOCK_SIZE);
961 strncpy(lseg->id,"LSEG",4);
962 lseg->size = sizeof(struct bLSEGblock)/sizeof(long);
964 memcpy(buf, lseg, sizeof(struct bLSEGblock));
965 #ifdef LITT_ENDIAN
966 swapEndian(buf, SWBL_LSEG);
967 #endif
969 newSum = adfNormalSum(buf, 8, LOGICAL_BLOCK_SIZE);
970 swLong(buf+8,newSum);
971 // *(long*)(buf+8) = swapLong((unsigned char*)&newSum);
973 nFct = adfEnv.nativeFct;
974 if (dev->isNativeDev)
975 rc=(*nFct->adfNativeWriteSector)(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
976 else
977 rc=adfWriteDumpSector(dev, nSect, LOGICAL_BLOCK_SIZE, buf);
979 if (rc!=RC_OK)
980 return RC_ERROR;
982 return RC_OK;
985 /*##########################################################################*/