2 * ADF Library. (C) 1997-1998 Laurent Clevy
26 extern struct Env adfEnv
;
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
);
43 (*adfEnv
.eFct
)("adfDevType : unknown device type");
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
)
61 printf("Cylinders = %ld\n",(long)dev
->cylinders
);
62 printf("Heads = %ld\n",(long)dev
->heads
);
63 printf("Sectors/Cyl = %ld\n\n",(long)dev
->sectors
);
64 if (!dev
->isNativeDev
)
65 printf("Dump device\n\n");
67 printf("Real device\n\n");
68 printf("Volumes = %d\n\n",dev
->nVol
);
72 printf("floppy dd\n"); break;
74 printf("floppy hd\n"); break;
75 case DEVTYPE_HARDDISK:
76 printf("harddisk\n"); break;
77 case DEVTYPE_HARDFILE:
78 printf("hardfile\n"); break;
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 (long)dev
->volList
[i
]->firstBlock
,
88 (long)dev
->volList
[i
]->firstBlock
+ dev
->volList
[i
]->totalBlocks
- 1,
89 dev
->volList
[i
]->volName
);
91 printf("%2d : %7ld ->%7ld\n", i
,
92 (long)dev
->volList
[i
]->firstBlock
,
93 (long)dev
->volList
[i
]->firstBlock
+ dev
->volList
[i
]->totalBlocks
- 1);
94 if (dev
->volList
[i
]->mounted
)
105 void adfFreeTmpVolList(struct List
*root
)
112 vol
= (struct Volume
*)cell
->content
;
113 if (vol
->volName
!=NULL
)
126 RETCODE
adfMountHdFile(struct Device
*dev
)
129 unsigned char buf
[512];
133 dev
->devType
= DEVTYPE_HARDFILE
;
135 dev
->volList
= (struct Volume
**)malloc(sizeof(struct Volume
*));
137 (*adfEnv
.eFct
)("adfMountHdFile : malloc");
141 vol
=(struct Volume
*)malloc(sizeof(struct Volume
));
143 (*adfEnv
.eFct
)("adfMountHdFile : malloc");
146 dev
->volList
[0] = vol
;
147 dev
->nVol
++; /* fixed by Dan, ... and by Gary */
151 dev
->cylinders
= dev
->size
/512;
156 vol
->reservedBlocks
= 2;
158 size
= dev
->size
+ 512-(dev
->size
%512);
159 //printf("size=%ld\n",size);
160 vol
->rootBlock
= ((size
/512)-1+vol
->reservedBlocks
)/2;
161 //printf("root=%ld\n",vol->rootBlock);
162 adfReadDumpSector(dev
, 0, 512, buf
);
163 vol
->rootBlock
= swapLong(buf
+8);
165 adfReadDumpSector(dev
, vol
->rootBlock
, 512, buf
);
166 found
= swapLong(buf
)==T_HEADER
&& swapLong(buf
+508)==ST_ROOT
;
168 (*adfEnv
.eFct
)("adfMountHdFile : rootblock not found");
171 vol
->totalBlocks
= vol
->rootBlock
*2;
180 * normal not used directly : called by adfMount()
182 * fills geometry fields and volumes list (dev->nVol and dev->volList[])
184 RETCODE
adfMountHd(struct Device
*dev
)
186 struct bRDSKblock rdsk
;
187 struct bPARTblock part
;
188 struct bFSHDblock fshd
;
189 struct bLSEGblock lseg
;
191 struct List
*vList
, *listRoot
;
196 if (adfReadRDSKblock( dev
, &rdsk
)!=RC_OK
)
199 dev
->cylinders
= rdsk
.cylinders
;
200 dev
->heads
= rdsk
.heads
;
201 dev
->sectors
= rdsk
.sectors
;
205 next
= rdsk
.partitionList
;
209 if (adfReadPARTblock( dev
, next
, &part
)!=RC_OK
) {
210 adfFreeTmpVolList(listRoot
);
211 (*adfEnv
.eFct
)("adfMountHd : malloc");
215 vol
=(struct Volume
*)malloc(sizeof(struct Volume
));
217 adfFreeTmpVolList(listRoot
);
218 (*adfEnv
.eFct
)("adfMountHd : malloc");
224 vol
->firstBlock
= rdsk
.cylBlocks
* part
.lowCyl
;
225 vol
->totalBlocks
= (part
.highCyl
- part
.lowCyl
+ 1)*rdsk
.cylBlocks
;
226 vol
->reservedBlocks
= part
.dosReserved
;
227 vol
->rootBlock
= (vol
->totalBlocks
-1 + vol
->reservedBlocks
)/2;
228 vol
->blockSize
= part
.blockSize
*4;
230 len
= min(31, part
.nameLen
);
231 vol
->volName
= (char*)malloc(len
+1);
233 adfFreeTmpVolList(listRoot
);
234 (*adfEnv
.eFct
)("adfMount : malloc");
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 */
244 vList
= listRoot
= newCell(NULL
, (void*)vol
);
246 vList
= newCell(vList
, (void*)vol
);
249 adfFreeTmpVolList(listRoot
);
250 (*adfEnv
.eFct
)("adfMount : newCell() malloc");
257 /* stores the list in an array */
258 dev
->volList
= (struct Volume
**)malloc(sizeof(struct Volume
*) * dev
->nVol
);
260 adfFreeTmpVolList(listRoot
);
261 (*adfEnv
.eFct
)("adfMount : unknown device type");
265 for(i
=0; i
<dev
->nVol
; i
++) {
266 dev
->volList
[i
]=(struct Volume
*)vList
->content
;
271 fshd
.segListBlock
= -1;
272 next
= rdsk
.fileSysHdrList
;
274 if (adfReadFSHDblock( dev
, next
, &fshd
)!=RC_OK
) {
275 for(i
=0;i
<dev
->nVol
;i
++) free(dev
->volList
[i
]);
277 (*adfEnv
.eFct
)("adfMount : adfReadFSHDblock");
283 next
= fshd
.segListBlock
;
285 if (adfReadLSEGblock( dev
, next
, &lseg
)!=RC_OK
) {
286 (*adfEnv
.wFct
)("adfMount : adfReadLSEGblock");
298 * normaly not used directly, called directly by adfMount()
300 * use dev->devType to choose between DD and HD
301 * fills geometry and the volume list with one volume
303 RETCODE
adfMountFlop(struct Device
* dev
)
306 struct bRootBlock root
;
311 if (dev
->devType
==DEVTYPE_FLOPDD
)
316 vol
=(struct Volume
*)malloc(sizeof(struct Volume
));
318 (*adfEnv
.eFct
)("adfMount : malloc");
324 vol
->totalBlocks
=(dev
->cylinders
* dev
->heads
* dev
->sectors
);
325 vol
->reservedBlocks
= 2;
326 vol
->rootBlock
= (vol
->totalBlocks
-1 + vol
->reservedBlocks
)/2;
327 vol
->blockSize
= 512;
330 if (adfReadRootBlock(vol
, vol
->rootBlock
, &root
)!=RC_OK
)
332 memset(diskName
, 0, 35);
333 memcpy(diskName
, root
.diskName
, root
.nameLen
);
335 vol
->volName
= strdup(diskName
);
337 dev
->volList
=(struct Volume
**) malloc(sizeof(struct Volume
*));
340 (*adfEnv
.eFct
)("adfMount : malloc");
343 dev
->volList
[0] = vol
;
346 /*printf("root=%d\n",vol->rootBlock); */
354 * mount a dump file (.adf) or a real device (uses adf_nativ.c and .h)
356 * adfInitDevice() must fill dev->size !
358 struct Device
* adfMountDev( char* filename
, BOOL ro
)
361 struct nativeFunctions
*nFct
;
365 dev
= (struct Device
*)malloc(sizeof(struct Device
));
367 (*adfEnv
.eFct
)("adfMountDev : malloc error");
373 /* switch between dump files and real devices */
374 nFct
= adfEnv
.nativeFct
;
375 dev
->isNativeDev
= (*nFct
->adfIsDevNative
)(filename
);
376 if (dev
->isNativeDev
)
377 rc
= (*nFct
->adfInitDevice
)(dev
, filename
,ro
);
379 rc
= adfInitDumpDevice(dev
,filename
,ro
);
381 free(dev
); return(NULL
);
384 dev
->devType
= adfDevType(dev
);
386 switch( dev
->devType
) {
390 if (adfMountFlop(dev
)!=RC_OK
) {
391 free(dev
); return NULL
;
395 case DEVTYPE_HARDDISK
:
396 /* to choose between hardfile or harddisk (real or dump) */
397 if (adfReadDumpSector(dev
, 0, 512, buf
)!=RC_OK
) {
398 (*adfEnv
.eFct
)("adfMountDev : adfReadDumpSector failed");
399 free(dev
); return NULL
;
402 /* a file with the first three bytes equal to 'DOS' */
403 if (!dev
->isNativeDev
&& strncmp("DOS",(char *)buf
,3)==0) {
404 if (adfMountHdFile(dev
)!=RC_OK
) {
405 free(dev
); return NULL
;
408 else if (adfMountHd(dev
)!=RC_OK
) {
409 /* Just return the device */
415 (*adfEnv
.eFct
)("adfMountDev : unknown device type");
425 * create PARTIALLY the sectors of the header of one harddisk : can not be mounted
426 * back on a real Amiga ! It's because some device dependant values can't be guessed...
428 * do not use dev->volList[], but partList for partitions information : start and len are cylinders,
430 * do not fill dev->volList[]
431 * called by adfCreateHd()
433 RETCODE
adfCreateHdHeader(struct Device
* dev
, int n
, struct Partition
** partList
)
436 struct bRDSKblock rdsk
;
437 struct bPARTblock part
;
443 memset((unsigned char*)&rdsk
,0,sizeof(struct bRDSKblock
));
444 memset((unsigned char*)&part
,0,sizeof(struct bPARTblock
));
447 rdsk
.rdbBlockHi
= (dev
->sectors
*dev
->heads
*2)-1;
449 rdsk
.hiCylinder
= dev
->cylinders
-1;
450 rdsk
.cylBlocks
= dev
->sectors
*dev
->heads
;
452 rdsk
.cylinders
= dev
->cylinders
;
453 rdsk
.sectors
= dev
->sectors
;
454 rdsk
.heads
= dev
->heads
;
456 rdsk
.badBlockList
= -1;
457 rdsk
.partitionList
= 1;
458 rdsk
.fileSysHdrList
= -1;
460 rdsk
.bootBlockList
= -1;
461 for ( i
= 0; i
< 5; i
++)
464 /* Clear all sectors in the header */
465 for (i
= rdsk
.rdbBlockLo
; i
<= rdsk
.rdbBlockHi
; i
++)
466 adfWriteBlockDev(dev
, i
, sizeof(part
), (unsigned char *)&part
);
468 if (adfWriteRDSKblock(dev
, &rdsk
)!=RC_OK
)
474 for(i
=0; i
<dev
->nVol
; i
++) {
477 memset(&part
, 0, sizeof(struct bPARTblock
));
484 len
= min(MAXNAMELEN
,strlen(partList
[i
]->volName
));
486 strncpy(part
.name
, partList
[i
]->volName
, len
);
488 if (partList
[i
]->reserved
>= 1)
489 reserved
= partList
[i
]->reserved
;
493 part
.surfaces
= dev
->heads
;
494 part
.blocksPerTrack
= dev
->sectors
;
495 part
.lowCyl
= partList
[i
]->startCyl
;
496 part
.highCyl
= partList
[i
]->startCyl
+ partList
[i
]->lenCyl
-1;
497 part
.maxTransfer
= 0x00ffffff;
498 part
.mask
= 0xfffffffe;
499 part
.dosReserved
= reserved
;
500 part
.numBuffer
= 100;
501 part
.vectorSize
= 16;
502 part
.blockSize
= 128;
503 part
.sectorsPerBlock
= 1;
504 part
.bootBlocks
= (reserved
< 2) ? reserved
: 2;
505 part
.flags
= (partList
[i
]->bootable
? 1 : 0) |
506 (partList
[i
]->nomount
? 2 : 0);
508 memcpy(part
.dosType
, partList
[i
]->volType
, 4);
510 if (adfWritePARTblock(dev
, j
, &part
))
522 * create a filesystem on a floppy device
523 * fills dev->volList[]
525 RETCODE
adfCreateFlop(struct Device
* dev
, char* volName
, int volType
)
528 (*adfEnv
.eFct
)("adfCreateFlop : dev==NULL");
531 dev
->volList
=(struct Volume
**) malloc(sizeof(struct Volume
*));
533 (*adfEnv
.eFct
)("adfCreateFlop : unknown device type");
536 dev
->volList
[0] = adfCreateVol( dev
, 0L, 80L, 2, volName
, volType
);
537 if (dev
->volList
[0]==NULL
) {
542 dev
->volList
[0]->blockSize
= 512;
543 if (dev
->sectors
==11)
544 dev
->devType
=DEVTYPE_FLOPDD
;
546 dev
->devType
=DEVTYPE_FLOPHD
;
555 * create a filesystem one an harddisk device (partitions==volumes, and the header)
557 * fills dev->volList[]
560 RETCODE
adfCreateHd(struct Device
* dev
, int n
, struct Partition
** partList
)
564 //struct Volume *vol;
566 if (dev
==NULL
|| partList
==NULL
|| n
<=0) {
567 (*adfEnv
.eFct
)("adfCreateHd : illegal parameter(s)");
571 dev
->volList
=(struct Volume
**) malloc(sizeof(struct Volume
*)*n
);
573 (*adfEnv
.eFct
)("adfCreateFlop : malloc");
577 if (memcmp(partList
[i
]->volType
, "DOS", 3) != 0) {
578 (*adfEnv
.eFct
)("adfCreateHd : Skipping non-DOS volume\n");
581 dev
->volList
[i
] = adfCreateVol( dev
,
582 partList
[i
]->startCyl
,
584 partList
[i
]->reserved
,
585 partList
[i
]->volName
,
586 partList
[i
]->volType
[3] );
587 if (dev
->volList
[i
]==NULL
) {
589 free( dev
->volList
[i
] );
593 (*adfEnv
.eFct
)("adfCreateHd : adfCreateVol() fails");
595 dev
->volList
[i
]->blockSize
= 512;
599 if (adfCreateHdHeader(dev
, n
, partList
)!=RC_OK
)
609 void adfUnMountDev( struct Device
* dev
)
612 struct nativeFunctions
*nFct
;
617 for(i
=0; i
<dev
->nVol
; i
++) {
618 free(dev
->volList
[i
]->volName
);
619 free(dev
->volList
[i
]);
625 nFct
= adfEnv
.nativeFct
;
626 if (dev
->isNativeDev
)
627 (*nFct
->adfReleaseDevice
)(dev
);
629 adfReleaseDumpDevice(dev
);
637 RETCODE
adfReadBlockDev( struct Device
* dev
, ULONG nSect
, ULONG size
, unsigned char* buf
)
639 struct nativeFunctions
*nFct
;
642 nFct
= adfEnv
.nativeFct
;
643 if (dev
->isNativeDev
)
644 rc
= (*nFct
->adfNativeReadSector
)(dev
, nSect
, size
, buf
);
646 rc
= adfReadDumpSector(dev
, nSect
, size
, buf
);
651 if (buf
[0] == 0 && buf
[1] == 0 && buf
[2] == 0 && buf
[3] == 0)
654 if ( Long(buf
+ 8) == 0)
657 if ( Long(buf
+ 8) != adfNormalSum(buf
,8,Long(buf
+ 4) * 4) )
666 RETCODE
adfWriteBlockDev( struct Device
* dev
, ULONG nSect
, ULONG size
, unsigned char* buf
)
668 struct nativeFunctions
*nFct
;
672 sum
= adfNormalSum(buf
, 8, Long(buf
+ 4) * 4);
675 nFct
= adfEnv
.nativeFct
;
676 if (dev
->isNativeDev
)
677 return (*nFct
->adfNativeWriteSector
)(dev
, nSect
, size
, buf
);
679 return adfWriteDumpSector(dev
, nSect
, size
, buf
);
687 adfReadRDSKblock( struct Device
* dev
, struct bRDSKblock
* blk
)
694 rc2
= adfReadBlockDev(dev
, 0, 256, buf
);
698 memcpy(blk
, buf
, 256);
700 /* big to little = 68000 to x86 */
701 swapEndian((unsigned char*)blk
, SWBL_RDSK
);
704 if ( strncmp(blk
->id
,"RDSK",4)!=0 ) {
705 (*adfEnv
.eFct
)("ReadRDSKblock : RDSK id not found");
709 if ( blk
->size
!= 64 )
710 (*adfEnv
.wFct
)("ReadRDSKBlock : size != 64\n");
712 if ( blk
->blockSize
!= 512 )
713 (*adfEnv
.wFct
)("ReadRDSKBlock : blockSize != 512\n");
715 if ( blk
->cylBlocks
!= blk
->sectors
*blk
->heads
)
716 (*adfEnv
.wFct
)( "ReadRDSKBlock : cylBlocks != sectors*heads");
727 adfWriteRDSKblock(struct Device
*dev
, struct bRDSKblock
* rdsk
)
729 unsigned char buf
[LOGICAL_BLOCK_SIZE
];
732 (*adfEnv
.wFct
)("adfWriteRDSKblock : can't write block, read only device");
736 memset(buf
,0,LOGICAL_BLOCK_SIZE
);
738 strncpy(rdsk
->id
,"RDSK",4);
739 rdsk
->size
= sizeof(struct bRDSKblock
)/sizeof(ULONG
);
740 rdsk
->blockSize
= LOGICAL_BLOCK_SIZE
;
741 rdsk
->badBlockList
= -1;
743 strncpy(rdsk
->diskVendor
,"ADFlib ",8);
744 strncpy(rdsk
->diskProduct
,"harddisk.adf ",16);
745 strncpy(rdsk
->diskRevision
,"v1.0",4);
747 memcpy(buf
, rdsk
, sizeof(struct bRDSKblock
));
749 swapEndian(buf
, SWBL_RDSK
);
752 return adfWriteBlockDev(dev
, 0, LOGICAL_BLOCK_SIZE
, buf
);
761 adfReadPARTblock( struct Device
* dev
, ULONG nSect
, struct bPARTblock
* blk
)
763 UCHAR buf
[ sizeof(struct bPARTblock
) ];
764 RETCODE rc2
, rc
= RC_OK
;
766 rc2
= adfReadBlockDev(dev
, nSect
, sizeof(struct bPARTblock
), buf
);
770 memcpy(blk
, buf
, sizeof(struct bPARTblock
));
772 /* big to little = 68000 to x86 */
773 swapEndian((unsigned char*)blk
, SWBL_PART
);
776 if ( strncmp(blk
->id
,"PART",4)!=0 ) {
777 (*adfEnv
.eFct
)("ReadPARTblock : PART id not found");
781 if ( blk
->size
!= 64 )
782 (*adfEnv
.wFct
)("ReadPARTBlock : size != 64");
784 if ( blk
->blockSize
!=128 ) {
785 (*adfEnv
.eFct
)("ReadPARTblock : blockSize!=512, not supported (yet)");
798 adfWritePARTblock(struct Device
*dev
, ULONG nSect
, struct bPARTblock
* part
)
800 unsigned char buf
[LOGICAL_BLOCK_SIZE
];
803 (*adfEnv
.wFct
)("adfWritePARTblock : can't write block, read only device");
807 memset(buf
,0,LOGICAL_BLOCK_SIZE
);
809 strncpy(part
->id
,"PART",4);
810 part
->size
= sizeof(struct bPARTblock
)/sizeof(ULONG
);
811 part
->blockSize
= LOGICAL_BLOCK_SIZE
;
812 part
->vectorSize
= 16;
813 part
->blockSize
= 128;
814 part
->sectorsPerBlock
= 1;
815 part
->dosReserved
= 2;
817 memcpy(buf
, part
, sizeof(struct bPARTblock
));
819 swapEndian(buf
, SWBL_PART
);
822 return adfWriteBlockDev(dev
, nSect
, LOGICAL_BLOCK_SIZE
, buf
);
830 adfReadFSHDblock( struct Device
* dev
, ULONG nSect
, struct bFSHDblock
* blk
)
832 UCHAR buf
[sizeof(struct bFSHDblock
)];
835 rc
= adfReadBlockDev(dev
, nSect
, sizeof(struct bFSHDblock
), buf
);
839 memcpy(blk
, buf
, sizeof(struct bFSHDblock
));
841 /* big to little = 68000 to x86 */
842 swapEndian((unsigned char*)blk
, SWBL_FSHD
);
845 if ( strncmp(blk
->id
,"FSHD",4)!=0 ) {
846 (*adfEnv
.eFct
)("ReadFSHDblock : FSHD id not found");
850 if ( blk
->size
!= 64 )
851 (*adfEnv
.wFct
)("ReadFSHDblock : size != 64");
862 adfWriteFSHDblock(struct Device
*dev
, ULONG nSect
, struct bFSHDblock
* fshd
)
864 unsigned char buf
[LOGICAL_BLOCK_SIZE
];
867 (*adfEnv
.wFct
)("adfWriteFSHDblock : can't write block, read only device");
871 memset(buf
,0,LOGICAL_BLOCK_SIZE
);
873 strncpy(fshd
->id
,"FSHD",4);
874 fshd
->size
= sizeof(struct bFSHDblock
)/sizeof(ULONG
);
876 memcpy(buf
, fshd
, sizeof(struct bFSHDblock
));
878 swapEndian(buf
, SWBL_FSHD
);
881 return adfWriteBlockDev(dev
, nSect
, LOGICAL_BLOCK_SIZE
, buf
);
890 adfReadLSEGblock(struct Device
* dev
, ULONG nSect
, struct bLSEGblock
* blk
)
892 UCHAR buf
[sizeof(struct bLSEGblock
)];
895 rc
= adfReadBlockDev(dev
, nSect
, sizeof(struct bLSEGblock
), buf
);
899 memcpy(blk
, buf
, sizeof(struct bLSEGblock
));
901 /* big to little = 68000 to x86 */
902 swapEndian((unsigned char*)blk
, SWBL_LSEG
);
905 if ( strncmp(blk
->id
,"LSEG",4)!=0 ) {
906 (*adfEnv
.eFct
)("ReadLSEGblock : LSEG id not found");
910 if ( blk
->next
!=-1 && blk
->size
!= 128 )
911 (*adfEnv
.wFct
)("ReadLSEGBlock : size != 128");
922 adfWriteLSEGblock(struct Device
*dev
, ULONG nSect
, struct bLSEGblock
* lseg
)
924 unsigned char buf
[LOGICAL_BLOCK_SIZE
];
927 (*adfEnv
.wFct
)("adfWriteLSEGblock : can't write block, read only device");
931 memset(buf
,0,LOGICAL_BLOCK_SIZE
);
933 strncpy(lseg
->id
,"LSEG",4);
934 lseg
->size
= sizeof(struct bLSEGblock
)/sizeof(ULONG
);
936 memcpy(buf
, lseg
, sizeof(struct bLSEGblock
));
938 swapEndian(buf
, SWBL_LSEG
);
941 return adfWriteBlockDev(dev
, nSect
, LOGICAL_BLOCK_SIZE
, buf
);
949 adfReadBOOTblock(struct Device
* dev
, ULONG nSect
, struct bBOOTblock
* blk
)
951 UCHAR buf
[sizeof(struct bBOOTblock
)];
954 rc
= adfReadBlockDev(dev
, nSect
, sizeof(struct bBOOTblock
), buf
);
958 memcpy(blk
, buf
, sizeof(struct bBOOTblock
));
960 /* big to little = 68000 to x86 */
961 swapEndian((unsigned char*)blk
, SWBL_BOOT
);
964 if ( strncmp(blk
->id
,"BOOT",4)!=0 ) {
965 (*adfEnv
.eFct
)("ReadBOOTblock : BOOT id not found");
969 if ( blk
->next
!=-1 && blk
->size
!= 128 )
970 (*adfEnv
.wFct
)("ReadBOOTBlock : size != 128");
981 adfWriteBOOTblock(struct Device
*dev
, ULONG nSect
, struct bBOOTblock
* lseg
)
983 unsigned char buf
[LOGICAL_BLOCK_SIZE
];
986 (*adfEnv
.wFct
)("adfWriteBOOTblock : can't write block, read only device");
990 memset(buf
,0,LOGICAL_BLOCK_SIZE
);
992 strncpy(lseg
->id
,"BOOT",4);
993 lseg
->size
= sizeof(struct bBOOTblock
)/sizeof(ULONG
);
995 memcpy(buf
, lseg
, sizeof(struct bBOOTblock
));
997 swapEndian(buf
, SWBL_BOOT
);
1000 return adfWriteBlockDev(dev
, nSect
, LOGICAL_BLOCK_SIZE
, buf
);
1005 RETCODE
adfWriteBOOT(struct Device
*dev
, const UBYTE
*code
, size_t size
)
1007 struct bRDSKblock rdsk
;
1008 struct bBOOTblock boot
;
1009 UBYTE buf
[LOGICAL_BLOCK_SIZE
];
1010 ULONG
*sector
, *next_block
;
1015 printf("adfWriteBOOT: Size must be a multiple of 4\n");
1019 rc
= adfReadRDSKblock(dev
, &rdsk
);
1023 /* Sector map of sectors we can use for boot code */
1024 sectors
= (size
+ sizeof(boot
.loadData
) - 1) / sizeof(boot
.loadData
);
1025 sector
= alloca((rdsk
.rdbBlockHi
- rdsk
.rdbBlockLo
+ 1) * sizeof(sector
[0]));
1027 /* Do we have space for the new boot code? */
1028 next_block
= &rdsk
.bootBlockList
;
1029 for (n
= 0, i
= rdsk
.rdbBlockLo
; i
<= rdsk
.rdbBlockHi
; i
++) {
1030 sector
[i
- rdsk
.rdbBlockLo
] = (ULONG
)-1;
1031 rc
= adfReadBlockDev(dev
, i
, sizeof(buf
), buf
);
1033 if (memcmp(buf
, "BOOT", 4) != 0)
1035 } else if (rc
& RC_BLOCKREAD
) {
1036 /* Skip unreadable blocks */
1041 next_block
= §or
[i
- rdsk
.rdbBlockLo
];
1044 sector
[i
- rdsk
.rdbBlockLo
] = (ULONG
)-2; /* Erase sector */
1046 *next_block
= (ULONG
)-1;
1049 printf("Needed %d sectors for the BOOT code, only found %d\n", sectors
, n
);
1053 /* Clear out unused sectors */
1054 memset(buf
, 0, 512);
1055 for (i
= rdsk
.rdbBlockLo
; i
<= rdsk
.rdbBlockHi
; i
++) {
1056 if (sector
[i
- rdsk
.rdbBlockLo
] == (ULONG
)-2)
1057 adfWriteBlockDev(dev
, i
, sizeof(buf
), buf
);
1060 /* Write the new boot code */
1061 n
= rdsk
.bootBlockList
;
1063 int longs
= (size
> sizeof(boot
.loadData
)) ? sizeof(boot
.loadData
) : size
;
1064 longs
= (longs
+ 3) / 4;
1065 boot
.size
= longs
+ 5;
1066 boot
.hostID
= 7; /* Default */
1067 boot
.next
= sector
[n
- rdsk
.rdbBlockLo
];
1068 memset(boot
.loadData
, 0xff, sizeof(boot
.loadData
));
1069 for (i
= 0; i
< longs
; i
++) {
1070 boot
.loadData
[i
] = *(ULONG
*)code
;
1075 adfWriteBOOTblock(dev
, n
, &boot
);
1077 n
= sector
[n
- rdsk
.rdbBlockLo
];
1080 return adfWriteRDSKblock(dev
, &rdsk
);
1083 /*##########################################################################*/