unadf-0.7.11a/0000755000000000000000000000000010557637655011557 5ustar rootrootunadf-0.7.11a/Bin/0000755000000000000000000000000010557637416012262 5ustar rootrootunadf-0.7.11a/Bin/Linux/0000755000000000000000000000000010534577034013353 5ustar rootrootunadf-0.7.11a/Bin/Linux/libadf.a0000644000000000000000000023101010534577034014733 0ustar rootroot! / 1165164089 0 0 0 2944 ` 999999999TTTTTTTTTTeeeeeeeeeeeeeee|||||| ېېېېېېېېېېېېېېېېېېېTTadfDevTypeadfWriteLSEGblockadfWriteFSHDblockadfWritePARTblockadfWriteRDSKblockadfReadLSEGblockadfReadFSHDblockadfReadPARTblockadfReadRDSKblockadfUnMountDevadfMountHdFileadfCreateFlopadfCreateHdHeaderadfCreateHdadfMountFlopadfFreeTmpVolListadfMountHdadfMountDevadfDeviceInfoisSectNumValidadfWriteBlockadfReadBlockadfCreateVoladfUnMountadfInstallBootBlockadfMountadfVolumeInfobitMaskswapEndianswapTableadfNormalSumadfBitmapSumadfBootSumadfBootSum2adfWriteBootBlockadfWriteRootBlockadfReadRootBlockadfReadBootBlockadfIsBlockFreeadfCountFreeBlocksadfSetBlockFreeadfSetBlockUsedadfGetFreeBlocksadfGet1FreeBlockadfFreeBitmapadfWriteBitmapExtBlockadfReadBitmapExtBlockadfReadBitmapBlockadfWriteBitmapBlockadfCreateBitmapadfWriteNewBitmapadfReadBitmapadfUpdateBitmapadfReleaseDumpDeviceadfCreateDumpDeviceadfWriteDumpSectoradfCreateHdFileadfReadDumpSectoradfInitDumpDeviceswLongswShortadfIsLeapadfDays2DateadfTime2AmigaTimeadfGiveCurrentTimefreeListnewCelldumpBlockChangedadfChgEnvPropadfEnvadfSetEnvFctadfGetVersionNumberadfGetVersionDateadfEnvCleanUpadfEnvInitDefaultWarningErrorVerboserwHeadAccessprogressBarmyReadSectormyWriteSectoradfInitNativeFctmyInitDevicemyReleaseDevicemyIsDevNativeisDirEmptyadfToRootDiradfIntlToUpperadfToUppermyToUpperadfWriteDirBlockadfWriteEntryBlockadfReadEntryBlockadfParentDiradfGetHashValueadfCreateEntryadfCreateFileadfCreateDiradfNameToEntryBlkadfChangeDiradfAccess2StringprintEntryadfEntBlock2EntryadfFreeEntryadfFreeDirListadfGetRDirEntadfGetDirEntadfSetEntryAccessadfSetEntryCommentadfRemoveEntryadfRenameEntryadfFileTruncateadfFileRealSizeadfEndOfFileadfPos2DataBlockadfWriteFileExtBlockadfWriteDataBlockadfWriteFileHdrBlockadfReadFileExtBlockadfReadDataBlockadfFileSeekadfReadNextFileBlockadfReadFileadfGetFileBlocksadfCreateNextFileBlockadfWriteFileadfFreeFileBlocksadfOpenFileadfFlushFileadfCloseFileadfEntry2CacheEntryadfGetCacheEntryadfWriteDirCBlockadfReadDirCBlockadfCreateEmptyCacheadfDelFromCacheadfPutCacheEntryadfAddInCacheadfUpdateCacheadfGetDirEntCacheadfBlockPtr2EntryNamepathadfCheckDiradfCheckFileadfCheckEntryadfFreeGenBlockadfReadGenBlockadfCheckParentadfUndelFileadfUndelDiradfUndelEntryadfGetDelEntadfFreeDelListadf_hd.o/ 1165164085 0 0 100644 11752 ` ELF 4( UEP t- t%tDtt~ ɉɸ$Ít&UWVS}]OD$D$4$LSEGCD$\$4$D$ 4$D$D$4$D$$W (t.U t$ D$<$T$PЁ[^_]ÍvE t$ D$<$D$$$ UWVS}]wD$D$4$FSHDC@\$D$4$D$ 4$D$D$4$D$$_ (t.U t$ D$<$T$PЁ[^_]ÍvE t$ D$<$D$$\ UWVS}]OD$D$4$PARTC@ǃǃǃǃD$\$4$D$ 4$D$D$4$D$$W (t+U t$ D$<$T$PЁ[^_]ËE t$ D$<$D$$čv'UWVS}] w!D$D$4$ǃhardRDSKC@CCǃADFlǃib ǃv1.0@disk@.adf@ \$D$4$D$4$D$D$4$D$$_ (t-t$ D$D$<$PЁ[^_]Ðt$ D$D$<$$&'U((E]M u}x t;\$ D$L$$Rt=]Ћu}]ÐT$ D$L$$uɋED$\$$UD$ $uubEXD$D$$9t $(]{t{t$1,1%$&'U((E]M u]}p t8t$ D$L$$Rt:v]Ћu}]ÐT$ D$L$$uɍ!t$D$$D$ $uR{@t $&[D$D$$19P$p1<$L%t&U((E]M u]}x t8t$ D$L$$Rt:v]Ћu}]ÐT$ D$L$$uɍAt$D$$D$ $uu{@t $Fu?[D$D$$19D$10$$U((E]u}H t>L$ D$D$$Rt@t&]Ћu}]ÐT$ D$D$$uŋE aL$D$$U D$$u M y@t $fE XD$D$$9t $4M yt $XU M BDBH19$|1$t&UWVS u~ ~D1vF@$$F$F 9Ѕ~ F$^ F (t4$Pu [^_]4$u [^_] [^_]Ív'UWVS}G $G$@WGG  0ȁ)) G GGF$FF t&V ЉV ~p\$ D$D$<$  ЃuEUM U ЃuV t(DF1[^_]$$ UVS u|$ÉFt{ED$E D$PD$4$D$ Ft^~ F @ t1 [^]É 1[^]$$$뱍v'UWVS uD$D$$DžtVFDž|xFEFEF84FDž Dž%7ld, "%s"%2d : %7ld ->%7ld , mountedGCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.4.rodata.str1.1.comment.note.GNU-stack@ 8' %+02?2rNs-Wg!0  % \`.5<GT[np&RB`+N{`  " q18 FS` heltL ?`7@`) adf_hd.cadfDevTypeadfEnvadfWriteLSEGblockmemsetmemcpyswapEndianadfNormalSumswLongadfWriteDumpSectoradfWriteFSHDblockadfWritePARTblockadfWriteRDSKblockadfReadLSEGblockadfReadDumpSectoradfReadFSHDblockadfReadPARTblockadfReadRDSKblockadfUnMountDevfreeadfReleaseDumpDeviceadfMountHdFilemallocadfCreateFlopadfCreateVoladfCreateHdHeaderstrlenstrncpyadfCreateHdadfMountFlopadfReadRootBlock__strdupadfFreeTmpVolListfreeListadfMountHdnewCelladfMountDevadfInitDumpDeviceadfDeviceInfoprintfputsstdout_IO_putcKQ    GPV     W`f   (:B   Y i      #) >D k  +1 Rci w}  4 D[a     ^ u           3 9  G M      4 K  \ b  p v    " (  6 <  K   G"# { n   !  Y& ':CI ~#+\p  6+^(ek )-4: R(Y_ ( (   !((. Zr   "-4%F*  06 >Ur{///0/12&//CH/aj/{0  )adf_disk.o/ 1165164085 0 0 100644 6800 ` ELF4( U1U MxA+A9]ÐU(uu}E ]}^(N^uy;^|>;^9(H tF|$ D$\$$RЋ]u}]$l(H u|$ D$\$$D$D$$m$$8xt&U(uu}E ]}N(^u~;^|>;^9(p tF|$ D$\$$RЋ]u}]$(p u|$ D$\$$붐t&D$D$$h$늉UWVSL ]$@ASSU PCCETV+VF F7I]nwadf_disk.cisSectNumValidadfWriteBlockadfEnvadfWriteDumpSectoradfReadBlockadfReadDumpSectoradfCreateVolmallocstrlenmemcpymemsetadfWriteBootBlockadfCreateBitmapadfGetFreeBlocksadfGiveCurrentTimeadfTime2AmigaTimeadfWriteRootBlockadfWriteNewBitmapfreeadfCreateEmptyCacheadfUpdateBitmapadfFreeBitmapadfUnMountadfInstallBootBlockadfReadBootBlockadfMountadfReadRootBlockadfReadBitmapadfVolumeInfoprintfputsstdout_IO_putcadfCountFreeBlocksadfDays2DatebitMaskP k        E `      %  + \z  7Ciq     4> JX dw     T" ">$[%|  $ )'05'Y^(ej'oz')*+'( ,d m ' ,  ' ,v  '    '  (  '  '  (3 : @ I 'U Z (adf_raw.o/ 1165164085 0 0 100644 4128 ` ELF 4( UWVS,U E E܉UkE<EEEt&UUE~Qz1;ut.uߋMMfAE ;ufuٍ&EEE@uUE+EЋU9tNE ,[^_]]]SK SE ЉTEK,[^_]$'UWVSUM <1~Y1EEt&9]t+UMT TL E9uɋE؃[^_]ÍUW1VuS1ۍvDTL T )ǃuӉ[^_]ÍUW}V1S1ۍv A AI ‰9փ uǻ։[^_]Í&UW}V1S1ۍv Q QI Ѝ9wtÍv[^_]U]] u}}DCOCSD$\$4$D$4${pt2{ u,t$D$<$t0]Ћu}]É4$D$$븍D$D$<$1҅t뮍v'USE@@@ H@ǀǀǀ$D$D$$D$$D$D$D$$E \$D$E$[]É'UVS]t$E D$E$t [^]ÐD$t$$D$$;u t$ [^]Ë[D$D$4$19t$@k&U}}]u\$D$<$t]u}]ÍD$D$<$uЋE D$\$$U D$$} u1E x u1댉$U ;Bt$1h$dQl( R\$ @V  '8  7SwapEndian: type do not existDOSWarning: Endian Swapping lengthadfReadRootBlock : id not foundadfReadRootBlock : invalid checksumadfReadBootBlock : DOS id not foundadfReadBootBlock : incorrect checksumGCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.1.rodata.str1.4.comment.note.GNU-stack@G   % +p 02p "?2 NB -Wo o g   8 G 'P4DA0YL`Xjq`adf_raw.cswapEndianswapTableadfEnvadfNormalSumadfBitmapSumadfBootSumadfBootSum2adfWriteBootBlockmemcpyadfWriteBlockswLongadfWriteRootBlockadfReadRootBlockadfReadBlockadfReadBootBlock0 =   8> )9 \|#3 K ]s   7 DJ  % 39 adf_bitm.o/ 1165164086 0 0 100644 6704 ` ELF4( UM } ]uȉE@4U )ڋ EU)ً]<2U)lj)})ƋDu]É'UW1VSUBrX)9vE\$$9~[^_]Ív'Uuu }]ˉE +M)‰))ø 2U )4B40 DUB80]u}] U]] }uىΉE +M)‰))Ƹ U )B4!DUB8]u}]Í'UWVS}u EE_ E9u}8tX\$<$uXG;GtkG 9tUE9u|Ȅt ~1ېU<$D$9u19u[^_]ËEUEEj`UED$ED$$ EÍUVSuV,~1ۋF4$9^,F4F,$F0F4$F8F0$F8[^]ÉUSE$D$D$$D$E \$D$E$[]ÍvUE ]uu\$D$E$u&D$\$4$D$4$1ҋ]Ћu]Í&UVS]t$E D$E$t [^]Ð$D$t$$D$D$D$4$19t$1[^]ÐUSE$D$D$$D$$D$D$$D$E \$D$E$[] UWVS UB+B H<  )i)ыUz,$MA4$UB8$MA0#EE9}uEX4$UB40uɉ$MA8$M~1ۉUB4$9]uMA4$$ [^_]ËEP@Z)9\$E$UB+B9} 1[^_]$( [^_]ËB4$$T [^_]ËUB4$MA8$$KUWVS}G,$:D$G,<$D$L$G <$D$_,SO01ҋ09uG,UH )‰))$L$<$t$kDž;w,9w,~(TG0uӋ9~\LMD$<$D$uvct&E뮋$ $t$G <$D$Ё[^_]Ë4$$[^_]$[^_]Ë$$[^_]Ë$$[^_]Ë$=4$%&U WVSM  )i)EӉP,$UB4B$UB0$UB8H119UB8Z40$UB40uB8$UB0$~1ۋUB4$9uUB4$$[^_]11-UB40\$$D$Wt6E<t(UB00\$$u$,랋UT$D$E$94DžGUB00B40\$$D$uj~9t/\$U$u$,늋E?1t&E$[^_]$[^_]ËU$aUB4$UB0.v'UX]]}u|$C $D$t]Ћu}]Dž|$C $D$uˋK,~2C81Džv09S,E܉$DžED$ ED$ED$E܉$ED$ED$ED$ ED$ED$|$C $D$1҅C4D$C00$D$C8;adfReadBitmapBlock : invalid checksumadfCreateBitmap : malloc, vol->bitmapTableadfCreateBitmap : malloc, vol->bitmapBlocksChgadfCreateBitmap : malloc, vol->bitmapBlocksadfWriteNewBitmap : malloc failedadfReadBitmap : malloc, vol->bitmapTableadfReadBitmap : malloc, vol->bitmapBlocksadfReadBitmap : sector out of rangeadfCreateBitmap : mallocadfCreateBitmap : sectListGCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.4.rodata.str1.1.comment.note.GNU-stack@  %+02P?2@4Nt-Wgp  X #F6FV g*xn]iP  '7>` Pasp ` Padf_bitm.cadfIsBlockFreebitMaskadfCountFreeBlocksadfSetBlockFreeadfSetBlockUsedadfGetFreeBlocksadfGet1FreeBlockadfFreeBitmapfreeadfWriteBitmapExtBlockmemcpyswapEndianadfWriteBlockadfReadBitmapExtBlockadfReadBlockadfReadBitmapBlockadfNormalSumadfEnvadfWriteBitmapBlockswLongadfCreateBitmapmallocadfWriteNewBitmapadfReadRootBlockadfWriteRootBlockadfReadBitmapisSectNumValidadfUpdateBitmapadfGiveCurrentTimeadfTime2AmigaTimer  O  Y  1HZl '7v#;G]<Sa  5CJPy Ak \ p  !        % C [    4 N \ v      #  8 ~  #     / G   !%W&j!adf_dump.o/ 1165164086 0 0 100644 3420 ` ELF84( USEX$t$$1[]UWVS$(b$_B$ED$$‰aE EuD$$ D$D$D$D$ $$UD$;$E BEBErBt<1G G G[^_]ҋ$$$$Dž$Dž땋$$$Džk$$$Dž9$$$Džt&UVSEU uX$ D$T$$t.t$D$D$ E$19u [^]É[^]ÉUVS ut[$ÉFtZED$E D$ FD$4$D$Ft>F 1 [^]$?$Hщ$&'UVSEU uX$ D$T$$t.t$D$D$ E$19u [^]É[^]ÉU$u}}]Ep$xupE D$;$D$D$$$D$D$Ë$EX1]u}]ËE D$v$u4$$y뼍&$[롋 tuE D$v$E@t$padfCreateDumpDevice : malloc devadfCreateDumpDevice : malloc nDevadfCreateHdFile : unknown device typemyInitDevice : fopen, read-only mode forcedwbadfCreateDumpDevice : fopenadfCreateDumpDevice : fseekrb+adfCreateHdFile : dev==NULLadfInitDumpDevice : mallocrbmyInitDevice : fopenGCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.4.rodata.str1.1.comment.note.GNU-stack@6  %x+x02x?2N-Wg     0!(-0+AHNT[b`nunFadf_dump.cadfReleaseDumpDevicefclosefreeadfCreateDumpDevicemallocfopenfseekfwriteadfEnvadfWriteDumpSectoradfCreateHdFileadfCreateVoladfReadDumpSectorfreadadfInitDumpDevice__errno_locationftell $ D ` ~       - ; BH =CQWf   "9Acm  *0adf_util.o/ 1165164086 0 0 100644 2624 ` ELF4( UU MAƈAQ]Í'UU MƈQ]ÍUQSM)kd9u1)iҐ[]9[1] UVS4]$EEEEEEEEEEEEҁn9|)Ӊ4$ҁn9}tEEȺ9|Mȃ)ËD9~E 0EES4[^]Ít&UWVS8EU$} uEkE<EE(kU2E 0~~_EEEEEEEEEEEEu~1ҍuĉLuE }N~EEM~:)EËuLE n9t$uE m9u䐃8[^_]ËE$tEt'U(uu]]}4$4$Pxp HUPsK SCE{؋u]}] US]t"Ct$][][]Ív'US]$ t$‹E BBtS[]$1UWVS }EE1$D$SK S$ ЉD$u$f1$t&$.D$t)B<_w֡D$‰$uס$ D$E}! [^_]newCell : malloc%5x %08x GCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.1.comment.note.GNU-stack@ %+02!? -H::XL   #0PA%2#DaW\f 6ot`O|adf_util.cswLongswShortadfIsLeapadfDays2DateadfTime2AmigaTimeadfGiveCurrentTimetimelocaltimefreeListfreenewCellmallocadfEnvdumpBlockprintfstdout_IO_putc  ) g  9r&1G[pzFadf_env.o/ 1165164086 0 0 100644 2880 ` ELF`4( U]Ít&'UUE w$$t&]]]]] Ë]]Ë] ]Ë]É'UESU M]ttt t []ÍU]ÍU]ÍU($Ít&'U $ $(t$&UED$3D$$ÍUED$AD$$ÍUED$MD$$ÍUED$[D$$ÍU}D$gWD$E D$ ED$$029@G%NW^gn0.7.1131th March, 2006adfInitDefaultEnv : mallocVerbose <%s> Error <%s> Warning <%s> %d %% done phy %ld / log %ld : %c Compilation error : #define LITT_ENDIAN must not exist GCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3).symtab.strtab.shstrtab.rel.text.data.bss.rel.rodata.rodata.str1.1.rodata.str1.4.comment.note.GNU-stack@ (  %+4,0 X <2K28Z-cs  P  g! ,(:5 I [in$$$`;0$adf_env.cChangedadfChgEnvPropadfEnvadfSetEnvFctadfGetVersionNumberadfGetVersionDateadfEnvCleanUpfreeadfEnvInitDefaultWarningErrorVerboserwHeadAccessprogressBarmallocadfInitNativeFctstderrfprintf!( 4 ; B I R Y b i r         & * 0 4: >D N X b ry   =FNn  $(adf_nativ.o/ 1165164087 0 0 100644 1384 ` ELF4( U1]É'U1]É'(U@@@@ ]Ít&U4$u|$4$|$]ÉUE@$$1Ð&US]$tC$1}CC1[]$/dev/myInitDevice : mallocGCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.1.comment.note.GNU-stack@ X %,+,02,?H-HuuX  w ( ,9@LM]P.kpadf_nativ.cmyReadSectormyWriteSectoradfInitNativeFctadfEnvmyInitDevicemyReleaseDevicemyIsDevNativefreemalloc! * 18 ? Fg adf_dir.o/ 1165164087 0 0 100644 12964 ` ELFH!4( U1UHt Lt]1]Ð&UUB B<1]UUB<vB <v ]Ít]BÍvUUB<w]B]Ðt&UWVS]}ut/1ۅ~t&U $;9u>[^_]1ۅ~t&U $;9uΐt&USE@@ ǀ$D$D$$D$$D$D$D$$E \$D$E$[]Ít&'USE$D$D$$D$$D$D$D$$E \$D$E$[]É'U(E }uu]D$E|$$t]Ћu}]Í&D$|$4$D$4$^D$D$<$9ua>usw 1ҀHO~$TFD$D$ HD$$D$1F$/$(&'U1ɉS]S<;S u []ÍD$T$$u֋E1ɉC<̐t&UWVS1ۃ E$tK1*U$[ҍ9tE uM̉غ98 )Ӊ[^_]Ít&'UWVSU]u B$DžwU\$$|$ D$$|$ËDC}|E܉$D$ D$D$E܉$ED$ED$ED$ ED$ED$t$FD$E$Fe[^_]ÍEĉ$D$ D$D$Eĉ$EȉD$ẺD$EЉD$ EԉD$E؉D$Ut$B $D$y&E$$R]tD$Et$$49uȋ5D$|$ $T$ED$$T$u$U|$$]t~EttUt$rUt$D$$OE\$$6t$D$E$‹U$l$t&UX]E ]}uu|$D$$t]u}]D$ t$|$$tˋUD$D$$4$wȋEEL$t$$UBE؃UE܉$ED$ ED$ED$E܉$ED$ED$ED$ ED$ED$E$D$T$CuW$t&1U D$$ 1$0C "E|$$D$딍t&'UXuuD$E ]]}4$D$t]u}]ÍD$ \$D$4$ D$D$$$EUL$\$$EЍE܉$ED$ ED$ED$E܉$ED$ED$ED$ ED$ED$FuuD$|$4$4$ 1E D$$ 1v$(D$ED$4$D$D$4$IF EUhU]]u}B$|$$EwEEUՉ\$|$ $D$E u]u}]1UދtۉËEU\$D$$uU9EuƋE|$ D$UD$$EUT$D$EՉ$u؋]jU2`U(]]ut$C<$D$t]u]ËE D$t$ $D$D$tljC<1ŐUE----rwedt-t-t-t-ta tp@tsyh]US$]CD$ D$C$D$C4D$C0D$C,D$C D$ C$D$C($+D$;tk$Mt8t3CtD$$\$ D$$[]ÐC$$WD$밍vC$GD$댍t&'UWVSl}u F<؉ڍD$ET$$ED$FF(D$ F$D$F D$$F)‰V,k<)ѺQN0FFF ꋇ)ʃV4v $`1҃l[^_]Í&$@FDFHOO I T [ }         12/'6?456SYs457)787w89;<g3=<33=^;|>999=!;L;-A1&CLR-17gA&*-i%).J Y_D%ERG <-O7vD*"2"`A~;$JU&E7:  adf_file.o/ 1165164088 0 0 100644 9484 ` ELF4( U]Ít&'U1҉Eu ]uu}}1ۃH~)AE98mE)Í9EuCtt]u}]Ãܐt&UE]@$Ðt&U Mt$u $|$}ʉËE҉uC?G~+)ʉȋM$t$|$]ËMt&'USEǀ@ @$D$D$$D$$D$D$D$$E \$D$E$1[]Uuu}E]} FuD$D$$D$$D$D$$D$$\$|$4$]1u}]ÍD$|$4$ٍ&'USE@ ǀ$D$D$$D$$D$D$D$$E \$D$E$1[]Í&UWVS }\$E D$E$D$\$<$D$<$wD$D$$9t $?t $(t $TE ;Gt $HwrD$E$tIu 1[^_]ÉD$E$u$ 1[^_]Ív$먐$vyt&'UE }}u]D$Et$$D$t$<$E@t]1u}]ÍvD$<$_D$D$4$9t $4?t $X wIGD$E$tEGD$E$g$U&$v$뫍&'UWVS]M CD9vʍCSD$CD$ C D$@$D$C„҉׋u+uVCD$S C DD$$[^_]ÅtыS T$D$$S tu말$v똋CD$SG+C둍v'U(]]}uKCɉEuOC3P|$T$4$@uCU9Bt $C1]u}]Ð3Ft)G~3HtA{ HtzC GK )ƒTC 눋EP뀍&SG)ȋTf$C tVC D$CD$${3C 놋C D$4$D${3C \$뛐t&UWVSU uV} CEFD:9CF҉EE;FE E~e}t\V]E +E)9~ËE\$<$ЉD$]UF^9U F9Eut4$F렋VF};D} F$E [^_]Ë~҉}M4$FE)CM ut&UWVS] UCЃD$ D$MAD$D$UB $MAUB$MAs1~!E11ɋP49{鋓DžtoMAt$T$E$~-E11P149ߋUuUB B19t$(1Ɂ[^_]$$[^_]ÍvUWVSuN~CGEȺ98)9uq$E~H^~V 1DHuEF BF@Bǂ$tgV G+F F B\BuRE;FE~1D89EuFUGGFW @GF^[^_]ËE;Fv7F؉^[^_]ËF UD$@D$$FD$F$D$FD$D$$떋F_D$F$D$*$F tKFU~$/FuVZG+FB\VUT$$$X&'UWVSE }PU@GEGE;GE uE taW]E +E)9~ËE\$t$Љ$]UG_9U G9Eut<$tcG뛋EE E [^_]ËGWUV<$t GI$xE E $xUU 뗍UVS0uED$E 4$D$U~"1ۍE4$D$9]E~1ۋE4$D$9]E$E$01[^]Ít&UWVS}>u9G:H,D$F<4$D$U ,D$ DD$D$T$4$Dž $Dž[^_]@9,D$F<4$D$U ,D$ DD$D$T$4$lDž  $,$B $B 2BB BB(B B>9tW@9s9G:C,D$T$$C$G:uBD$D$$BD$ E D$F<4$D$B$+G:6G:+C,D$T$$CC$D$D$$DžE ,D$$D$$Džq$BDžU$^Dž9$^$Dž$^B$$Džt&UVSPuF t V(Ft2F(t2^FDAu VFB D^(ue[^]Ë^FDE$D$ äD$\$E$ED$ED$ED$ ED$ED$FD$@D$$AuY $e[^]Ít&D$@D$$FD$F $D$^(!\$F $D$D$ F\$D$$d&US]tB$C t$Ct$C$][]t&[]adfReadFileExtBlock : invalid checksumadfReadFileExtBlock : type T_LIST not foundadfReadFileExtBlock : stype ST_FILE not foundadfReadFileExtBlock : headerKey!=nSectadfReadFileExtBlock : highSeq out of rangeadfReadFileExtBlock : parent out of rangeadfReadFileExtBlock : extension out of rangeadfReadDataBlock : invalid checksumadfReadDataBlock : id T_DATA not foundadfReadDataBlock : dataSize incorrectadfReadDataBlock : headerKey out of rangeadfReadDataBlock : nextData out of rangeadfReadNextFileBlock : seqnum incorrectadfGetFileBlocks : less blocks than expectedadfCreateNextFileBlock : mallocadfWritefile : no more free sector availbaleadfFileOpen : device is mounted 'read only'adfFileOpen : file "%s" not found.adfFileOpen : file already existserroradfReadNextFileBlock : mallocadfGetFileBlocks : mallocwaadfFileOpen : access deniedadfFileOpen : mallocrGCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.4.rodata.str1.1.comment.note.GNU-stack@f L  %+02?2uN7-Wddg@  ` >s@.{> Ku\ qx Ep" ;5<+H }Y Bp 4"4DSVadf_file.c.LC19.LC26.LC20adfFileTruncateadfFileRealSizeadfEndOfFileadfPos2DataBlockadfWriteFileExtBlockmemcpyswapEndianadfNormalSumswLongadfWriteBlockadfWriteDataBlockadfWriteFileHdrBlockadfReadFileExtBlockadfReadBlockadfEnvisSectNumValidadfReadDataBlockadfFileSeekadfReadNextFileBlockmallocadfReadFileadfGetFileBlocksadfCreateNextFileBlockadfGet1FreeBlockmemsetadfSetBlockFreeadfWriteFileadfFreeFileBlocksfreeadfOpenFileadfReadEntryBlockadfNameToEntryBlkadfCreateFilesprintfadfFlushFileadfGiveCurrentTimeadfTime2AmigaTimeadfUpdateBitmapadfUpdateCacheadfCloseFileaq %7Gl G[k&,CISY5KZ`sy%Fci[n;  L k  E K a g  #5 #   $8 I i # %  [  " "    -!Q%t%((*!+;Ad*+do~ $,+ F i- .(DJ[(i(/I0aq1*2".1(@(K(X(adf_cache.o/ 1165164088 0 0 100644 6464 ` ELF4( UVSu] FC@KCfC fCfCCCT$ $D$KDH҈S~ IҍC4L$T$$KCDƒ[^]Ðt&DCIUWVSE U}tVN V ЉFVN V ЉGFV N  V  ЉGVOfF fG VfF fGVfF ЋUfGD.GD/VGT$ $D$OD9EȉET0҈W~LҍG4L$T$$OGD84U Dt[^_]Ít&UVSu Ep!$D$D$$D$$D$D$D$ $E\$t$$[^]Í&'UE u}}]D$Et$$t]Ћu}]Í&D$t$<$D$<$_D$D$4$9t $?!t $$E 1;Gz$H1fU]]uu }tvD$D$<$tltW$lEDžDž|$\$$Ћ]u}]É낍&F뫐t&UB 똉E$;$뚍UWVSE Dž\Dž`lXlD$E|$$`xE1l]D$ED$l$E9l`xM9Ⱦ))9},D+t.t&9u.;XulD$pxD$E$`|\tu;1Ĭ[^_]Ät$t&9x뱉xv9ˍ+)X9uI\pD$E$lD$\D$E$lD$\Dž|D$E$E$&UWVS E ]8Et84$D$CD$F$CD$F$C D$F$CD$F$CD$F$CNUD.CD/CST$ $D$CSET80CS4tCT$4$D$SCTtMD [^_]É'UWVS,D$Elu$U &T$D$E$E~#1ۍ|$t$$9ߋuEXED$T$$T$D$E$1҅u>,[^_]ËU$u1$,[^_]Á,[^_]ÍD$D$4$U tquzU BDžDžD$E$D$t$\$E$\UB $냍&UWV1S,D$E$U |$D$E$bE1ۉM썕hET$D$<$h;MU)ЋUET$D$<$|$D$E$‹t#t8U$1҅,[^_]Ã9/$,1[^_]9K|DUBD$E D$U$ED$U T$E$IoÍE+T$D$<$Dž)U;}%DLT:\89uD:;u&UWVSlD$E D$E$t1Ĭ[^_]Ëd1Dž`D$ElET$$ux1E`\$$``uEt ;>9xm$8HllD$ED$$~E$C,lCE$CpCtCC(D$ C$D$C D$x$zifff)ЉS,f)|f)ɉK0i{fff)ЅC4\$$Ɖ`CUD$ET$$`B$4$1| $ԋC$4$1adfReadDirCBlock : invalid checksumadfReadDirCBlock : T_DIRC not foundadfReadDirCBlock : headerKey!=nSectadfCreateEmptyCache : unknown secTypeadfUpdateCache : entry not foundadfAddInCache : unknown secTypeadfCreateDir : nCache==-1GCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.4.rodata.str1.1.comment.note.GNU-stack@  %<+<02<?2N.-W[[gp   !(<9 KVcjxi    0 Y/ lAS[bkxadf_cache.cadfEntry2CacheEntrymemcpyadfGetCacheEntryadfWriteDirCBlockswapEndianadfNormalSumswLongadfWriteBlockadfReadDirCBlockadfReadBlockadfEnvadfCreateEmptyCachememsetadfGet1FreeBlockadfDelFromCacheadfSetBlockFreeadfUpdateBitmapadfPutCacheEntryswShortadfAddInCacheadfUpdateCacheadfGetDirEntCacheadfReadEntryBlocknewCellmalloc__strdupadfDays2DateadfFreeEntryadfFreeDirListfreev    P ` x  0 KV\hn) w6  /5 2DVi|  F u   3 A G      # [  }    (  V        !  ` !  " " #v $%&&%adf_link.o/ 1165164088 0 0 100644 1028 ` ELFl4( UEt1ÍD$E D$E$ED1 USD$E D$E$E<؉ڍET$D$$1[]GCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3).symtab.strtab.shstrtab.rel.text.data.bss.comment.note.GNU-stack@ %+0-9!!I  @ A"4Pb9adf_link.cadfBlockPtr2EntryNameadfReadEntryBlockpathmemcpy.w adf_salv.o/ 1165164089 0 0 100644 4920 ` ELF 4( U1]É'UW1VS1ہ,UED$E$D$E@U11'vEU;T0t $D9]~ME|$0D$E$UE;Bt $E9E؅u9]E$E$,1[^_]ËE;T8t $DU;Bt$ht&;]UD$E8$D$;Et $s9t $$E9Yt$Dy'U(uu }}]\$t$<$Utt0]u}]ÍvE\$t$<$D$ ׍&E\$t$<$D$ 뷍&UE@t E]]Ð&UH]E] }uu|$\$$ui  ʉ ЉFEH AQ QIF Ѓ~F t1ҋ]Ћu}]ÉwCt׋EP Dž<v^D]ՉL$D$$$DFEH AQ QI 1҉FZ땍v'UVS0u] 4$\$uAED$\$4$}u E1҃v$0[^]$㍶'UWVS\}E <$D$uyUE ;SUED$<$T$u~[1t&E<$D$9u~8E<$D$uDž\[^_]Ë]~@1vE<$D$9u~E<$D$u랋E$E$E t$<$D$gU]$D$D$UDB\$t$<$D$ Gu)<$$DžEt$<$D$‰UH]] }}u\$<$uE;t!$P]u}]ËUB<$D$t9GtU<$D$tD$\$<$t뛋U]$D$D$UDB<$D$UB\$<$D$ D$Gu<$t&"UD$<$T$U<$D$뿍t&'U(uu}}]\$t$<$Ett5]1u}]ÍE \$ t$<$D$ҍ&E \$ t$<$D$벍&UWVSu^;^1EEEE9^|b\$4$tEup|$\$4$uċG tuEt]E|$$9^EE}tEtE98t<$E[^_]$t)y|$$EEE8E볍&UVSut$[uu[^]adfCheckFile : headerKey incorrectadfCheckFile : seqNum incorrectadfCheckFile : nextData incorrectadfCheckFile : dataSize incorrectadfCheckFile : extBlock parent incorrectadfCheckParent : parent doesn't existsadfCheckParent : parent secType is incorrectadfUndelFile : the given parent sector isn't the entry parentadfUndelDir : the given parent sector isn't the entry parentGCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3).symtab.strtab.shstrtab.rel.text.data.bss.rodata.str1.4.comment.note.GNU-stack@@  0 % + 02 ? -H: : XL @  { %6=QVguPpVsP-U9pG T\c 0radf_salv.cadfCheckDiradfCheckFileadfGetFileBlocksadfEnvadfReadFileExtBlockfreeadfReadDataBlockadfCheckEntryadfReadEntryBlockadfFreeGenBlockadfReadGenBlockadfReadBlockstrncpy__strdupadfCheckParentadfIsBlockFreeadfUndelFileadfSetBlockUsedadfCreateEntryadfUpdateBitmapadfAddInCacheadfUndelDiradfUndelEntryadfGetDelEntnewCellmallocadfFreeDelListfreeList5 ou       !' Ykq   # Cn 28 j !?V a t 0HS t(J_Hc  ! ' b < #unadf-0.7.11a/Boot/0000755000000000000000000000000010534557264012452 5ustar rootrootunadf-0.7.11a/Boot/stdboot3.bbk0000644000000000000000000000200010534557264014663 0ustar rootrootDOS=spC>p%NJg "@"NbCNJg @ hpNupNudos.libraryexpansion.libraryunadf-0.7.11a/Demo/0000755000000000000000000000000010534613554012426 5ustar rootrootunadf-0.7.11a/Demo/unadf.c0000644000000000000000000004113110534574650013672 0ustar rootroot/* * unadf 1.0 * * * tested under Linux and Win32 * * This file is part of ADFLib. * * ADFLib is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * ADFLib is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #define UNADF_VERSION "1.0" #include #include #include #include "adflib.h" /* The portable way used to create a directory is to call the MKDIR command via the * system() function. * It is used to create the 'dir1' directory, like the 'dir1/dir11' directory */ /* the portable way to check if a directory 'dir1' already exists i'm using is to * do fopen('dir1','rb'). NULL is returned if 'dir1' doesn't exists yet, an handle instead */ #define MKDIR "mkdir" #ifdef WIN32 #define DIRSEP '\\' #else #define DIRSEP '/' #endif /* WIN32 */ #define EXTBUFL 1024*8 void help() { puts("unadf [-lrcsp -v n] dumpname.adf [files-with-path] [-d extractdir]"); puts(" -l : lists root directory contents"); puts(" -r : lists directory tree contents"); puts(" -c : use dircache data (must be used with -l)"); puts(" -s : display entries logical block pointer (must be used with -l)"); putchar('\n'); puts(" -v n : mount volume #n instead of default #0 volume"); putchar('\n'); puts(" -p : send extracted files to pipe (unadf -p dump.adf Pics/pic1.gif | xv -)"); puts(" -d dir : extract to 'dir' directory"); } void printEnt(struct Volume *vol, struct Entry* entry, char *path, BOOL sect) { /* do not print the links entries, ADFlib do not support them yet properly */ if (entry->type==ST_LFILE || entry->type==ST_LDIR || entry->type==ST_LSOFT) return; if (entry->type==ST_DIR) printf(" "); else printf("%7ld ",entry->size); printf("%4d/%02d/%02d %2d:%02d:%02d ",entry->year, entry->month, entry->days, entry->hour, entry->mins, entry->secs); if (sect) printf(" %06ld ",entry->sector); if (strlen(path)>0) printf(" %s/",path); else printf(" "); if (entry->type==ST_DIR) printf("%s/",entry->name); else printf("%s",entry->name); if (entry->comment!=NULL && strlen(entry->comment)>0) printf(", %s",entry->comment); putchar('\n'); } void extractFile(struct Volume *vol, char* name, char* path, unsigned char *extbuf, BOOL pflag, BOOL qflag) { struct File *file; FILE* out; long n; char *filename; filename = NULL; if (pflag) out = stdout; else { if (strlen(path)>0) { filename=(char*)malloc(sizeof(char)* (strlen(path)+1+strlen(name)+1) ); if (!filename) return; sprintf(filename,"%s%c%s",path,DIRSEP,name); out = fopen(filename, "wb"); } else out = fopen(name, "wb"); if (!out) return; } file = adfOpenFile(vol, name, "r"); if (!file) { fclose(out); return; } n = adfReadFile(file, EXTBUFL, extbuf); while(!adfEndOfFile(file)) { fwrite(extbuf, sizeof(unsigned char), n, out); n = adfReadFile(file, EXTBUFL, extbuf); } if (n>0) fwrite(extbuf, sizeof(unsigned char), n, out); if (!pflag) fclose(out); adfCloseFile(file); if (!qflag) { if (filename!=NULL) printf("x - %s\n", filename); else printf("x - %s\n", name); } if (filename!=NULL) free(filename); } void extractTree(struct Volume *vol, struct List* tree, char *path, unsigned char *extbuf, BOOL pflag, BOOL qflag) { struct Entry* entry; char *buf; char sysbuf[200]; while(tree) { entry = (struct Entry*)tree->content; if (entry->type==ST_DIR) { buf = NULL; if (strlen(path)>0) { buf=(char*)malloc(strlen(path)+1+strlen(entry->name)+1); if (!buf) return; sprintf(buf,"%s%c%s",path,DIRSEP,entry->name); sprintf(sysbuf,"%s %s",MKDIR,buf); if (!qflag) printf("x - %s%c\n",buf,DIRSEP); } else { sprintf(sysbuf,"%s %s",MKDIR,entry->name); if (!qflag) printf("x - %s%c\n",entry->name,DIRSEP); } if (!pflag) system(sysbuf); if (tree->subdir!=NULL) { if (adfChangeDir(vol,entry->name)==RC_OK) { if (buf!=NULL) extractTree(vol,tree->subdir,buf,extbuf, pflag, qflag); else extractTree(vol,tree->subdir,entry->name,extbuf, pflag, qflag); adfParentDir(vol); } else { if (strlen(path)>0) fprintf(stderr,"ExtractTree : dir \"%s/%s\" not found.\n",path,entry->name); else fprintf(stderr,"ExtractTree : dir \"%s\" not found.\n",entry->name); } } if (buf!=NULL) free(buf); } else if (entry->type==ST_FILE) { extractFile(vol,entry->name,path,extbuf, pflag, qflag); } tree = tree->next; } } void printTree(struct Volume *vol, struct List* tree, char* path, BOOL sect) { char *buf; struct Entry* entry; while(tree) { printEnt(vol, tree->content, path, sect); if (tree->subdir!=NULL) { entry = (struct Entry*)tree->content; if (strlen(path)>0) { buf=(char*)malloc(sizeof(char)* (strlen(path)+1+strlen(entry->name)+1) ); if (!buf) { fprintf(stderr,"printTree : malloc error\n"); return; } sprintf(buf,"%s/%s", path, entry->name); printTree(vol, tree->subdir, buf, sect); free(buf); } else printTree(vol, tree->subdir, entry->name, sect); } tree = tree->next; } } void printDev(struct Device* dev) { printf("Device : "); switch(dev->devType){ case DEVTYPE_FLOPDD: printf("Floppy DD"); break; case DEVTYPE_FLOPHD: printf("Floppy HD"); break; case DEVTYPE_HARDDISK: printf("Harddisk"); break; case DEVTYPE_HARDFILE: printf("Hardfile"); break; default: printf("???"); break; } printf(". Cylinders = %ld, Heads = %ld, Sectors = %ld",dev->cylinders,dev->heads,dev->sectors); printf(". Volumes = %d\n",dev->nVol); } void printVol(struct Volume* vol, int volNum) { printf("Volume : "); switch(vol->dev->devType) { case DEVTYPE_FLOPDD: printf ("Floppy 880 KBytes,"); break; case DEVTYPE_FLOPHD: printf ("Floppy 1760 KBytes,"); break; case DEVTYPE_HARDDISK: printf ("HD partition #%d %3.1f KBytes,", volNum, (vol->lastBlock - vol->firstBlock +1) * 512.0/1024.0); break; case DEVTYPE_HARDFILE: printf ("HardFile %3.1f KBytes,", (vol->lastBlock - vol->firstBlock +1) * 512.0/1024.0); break; default: printf ("???,"); } if (vol->volName!=NULL) printf(" \"%s\"", vol->volName); printf(" between sectors [%ld-%ld].",vol->firstBlock, vol->lastBlock); printf(" %s ",isFFS(vol->dosType) ? "FFS" : "OFS"); if (isINTL(vol->dosType)) printf ("INTL "); if (isDIRCACHE(vol->dosType)) printf ("DIRCACHE "); printf(". Filled at %2.1f%%.\n", 100.0- (adfCountFreeBlocks(vol)*100.0)/(vol->lastBlock - vol->firstBlock +1) ); } void processFile(struct Volume *vol, char* name, char* path, unsigned char *extbuf, BOOL pflag, BOOL qflag) { char *sepptr, *cdstr, *fullname, *filename; char *bigstr; FILE *tfile; adfToRootDir(vol); sepptr = strchr(name, '/'); if (sepptr==NULL) { extractFile(vol, name, path, extbuf, pflag, qflag); } else { /* the all-in-one string : to call system(), to find the filename, the convert dir sep char ... */ bigstr=(char*)malloc(strlen(MKDIR)+1+strlen(path)+1+strlen(name)+1); if (!bigstr) { fprintf(stderr,"processFile : malloc"); return; } /* to build to extract path */ if (strlen(path)>0) { sprintf(bigstr,"%s %s%c%s",MKDIR,path,DIRSEP,name); cdstr = bigstr+strlen(MKDIR)+1+strlen(path)+1; } else { sprintf(bigstr,"%s %s",MKDIR,name); cdstr = bigstr+strlen(MKDIR)+1; } /* the directory in which the file will be extracted */ fullname = bigstr+strlen(MKDIR)+1; /* finds the filename, and separates it from the path */ filename = strrchr(bigstr,'/')+1; filename[-1]='\0'; sepptr = cdstr; /* find the end of the first dir to create */ while(sepptr[0]!='/' && sepptr[0]!='\0') sepptr++; while(strlen(cdstr)>0) { if (sepptr[0]=='/') { /* not the last one */ sepptr[0]='\0'; if (adfChangeDir(vol,cdstr)!=RC_OK) return; tfile = fopen(fullname,"r"); /* the only portable way to test if the dir exists */ if (tfile==NULL) { /* does't exist : create it */ if (!pflag) system(bigstr); if (!qflag) printf("x - %s%c\n",fullname,DIRSEP); } else fclose(tfile); sepptr[0] = DIRSEP; /* converts the '/' to '/' or '\' */ cdstr = sepptr+1; /* next beginning of the next dir to create */ /* to find the end of the next dir */ sepptr++; while(sepptr[0]!='/' && sepptr[0]!='\0') sepptr++; } else { /* the last one */ if (adfChangeDir(vol,cdstr)!=RC_OK) return; tfile = fopen(fullname,"r"); if (tfile==NULL) { if (!pflag) system(bigstr); if (!qflag) printf("x - %s%c\n",fullname,DIRSEP); } else fclose(tfile); cdstr = cdstr+strlen(cdstr); /* at the end, ends the while loop */ } } extractFile(vol, filename, fullname, extbuf, pflag, qflag); free(bigstr); } } int main(int argc, char* argv[]) { int i, j; BOOL rflag, lflag, xflag, cflag, vflag, sflag, dflag, pflag, qflag; struct List* files, *rtfiles; char *devname, *dirname; char strbuf[80]; unsigned char *extbuf; int vInd, dInd, fInd, aInd; BOOL nextArg; struct Device *dev; struct Volume *vol; struct List *list, *cell; int volNum; BOOL true = TRUE; if (argc<2) { help(); exit(0); } rflag = lflag = cflag = vflag = sflag = dflag = pflag = qflag = FALSE; vInd = dInd = fInd = aInd = -1; xflag = TRUE; dirname = NULL; devname = NULL; files = rtfiles = NULL; volNum = 0; fprintf(stderr,"unADF v%s : a unzip like for .ADF files, powered by ADFlib (v%s - %s)\n\n", UNADF_VERSION, adfGetVersionNumber(),adfGetVersionDate()); /* parse options */ i=1; while(i=dev->nVol) { fprintf(stderr,"This device has only %d volume(s), aborting.\n",dev->nVol); exit(1); } vol = adfMount(dev, volNum, TRUE); if (!vol) { adfUnMountDev(dev); fprintf(stderr, "Can't mount the volume\n"); adfEnvCleanUp(); exit(1); } if (!qflag) { printVol(vol, volNum); putchar('\n'); } if (cflag && isDIRCACHE(vol->dosType) && lflag) { adfChgEnvProp(PR_USEDIRC,&true); if (!qflag) puts("Using dir cache blocks."); } if (lflag) { if (!rflag) { cell = list = adfGetDirEnt(vol,vol->curDirPtr); while(cell) { printEnt(vol,cell->content,"", sflag); cell = cell->next; } adfFreeDirList(list); } else { cell = list = adfGetRDirEnt(vol,vol->curDirPtr,TRUE); printTree(vol,cell,"", sflag); adfFreeDirList(list); } }else if (xflag) { if (rtfiles!=NULL) { files = rtfiles; while(files!=NULL) { if (dirname!=NULL) processFile(vol, (char*)files->content, dirname, extbuf, pflag, qflag); else processFile(vol, (char*)files->content, "", extbuf, pflag, qflag); files = files->next; } freeList(rtfiles); } else { cell = list = adfGetRDirEnt(vol,vol->curDirPtr,TRUE); if (dirname==NULL) extractTree(vol, cell, "", extbuf, pflag, qflag); else extractTree(vol, cell, dirname, extbuf, pflag, qflag); adfFreeDirList(list); } } else help(); free(extbuf); adfUnMount(vol); adfUnMountDev(dev); adfEnvCleanUp(); return(0); } unadf-0.7.11a/Demo/Makefile0000644000000000000000000000071610534613554014072 0ustar rootroot# unadf LIBDIR=../Lib LIBNAME=libadf.a DEPEND=makedepend CFLAGS=-I$(LIBDIR) -O2 -Wall -Wno-uninitialized -pedantic LDFLAGS=-L$(LIBDIR) -ladf EXES= unadf all: $(EXES) run: $(EXES) unadf -h unadf -lrcs -v 1 ../../hd.adf lib: cd $(LIBDIR) && $(MAKE) unadf: lib unadf.o $(CC) $(CFLAGS) -o $@ unadf.o $(LDFLAGS) clean: (rm *.o $(EXES) core newdev *.exe *~) || true echo >.depend dep: $(DEPEND) -f.depend -v -- $(CFLAGS) -- *.[ch] include .depend unadf-0.7.11a/Demo/Extdir/0000755000000000000000000000000010534557264013672 5ustar rootrootunadf-0.7.11a/Demo/Extdir/.info0000644000000000000000000000116410534557264014630 0ustar rootroot9PHQ@22d@Z(9 $ $ $ $$$ ?03777*77?76?9h5UUUUU\@@@ @ @ @@?0"UUUUUP????*????unadf-0.7.11a/Demo/unadf.usage0000644000000000000000000000067210534557264014563 0ustar rootrootunadf [-lrcsp -v n] dumpname.adf [files-with-path] [-d extractdir] -l : lists root directory contents -r : lists directory tree contents -c : use dircache data (must be used with -l) -s : display entries logical block pointer (must be used with -l) -v n : mount volume #n instead of default #0 volume -p : send extracted files to pipe (unadf -p dump.adf Pics/pic1.gif | xv -) -d dir : extract to 'dir' directory unadf-0.7.11a/Demo/.depend.bak0000644000000000000000000000000110534613270014404 0ustar rootroot unadf-0.7.11a/Demo/.depend0000644000000000000000000000000110546012054013644 0ustar rootroot unadf-0.7.11a/Demo/unadf.output0000644000000000000000000022222010534557264015012 0ustar rootrootDevice : Harddisk. Cylinders = 980, Heads = 10, Sectors = 17. Volumes = 2 Volume : HD partition #0 8500.0 KBytes, "DH0" between sectors [340-17339]. FFS DIRCACHE . Filled at 88.9%. Using dir cache blocks. 632 1996/10/10 21:32:53 008509 Expansion.info 632 1991/09/29 22:23:02 008512 WBStartup.info 632 1992/09/02 12:40:52 008515 Devs.info 632 1992/09/02 13:32:10 008521 Utilities.info 848 1995/06/17 17:34:16 008524 Disk.info 724 1992/09/02 12:40:49 008527 Prefs.info 632 1992/09/02 12:40:51 008530 System.info 632 1996/10/10 21:36:26 008533 Tools.info 1172 1992/09/02 12:34:04 008536 Trashcan.info 1991/09/29 22:23:01 008542 Trashcan/ 1992/09/02 12:40:53 008544 Storage/ 632 1991/09/29 22:23:04 008612 Storage/Monitors.info 632 1992/09/02 12:40:53 008615 Storage/Printers.info 632 1992/09/02 11:57:44 008618 Storage/DOSDrivers.info 632 1992/09/02 11:58:21 008621 Storage/DataTypes.info 632 1992/09/02 11:57:45 008624 Storage/Keymaps.info 1996/10/09 20:33:38 008627 Storage/DOSDrivers/ 492 1991/09/29 22:23:07 009421 Storage/DOSDrivers/PC0.info 481 1991/09/29 22:23:08 009423 Storage/DOSDrivers/RAD.info 481 1991/09/29 22:23:09 009425 Storage/DOSDrivers/AUX.info 549 1991/09/29 22:23:06 009427 Storage/DOSDrivers/RAD 664 1991/09/29 22:23:10 009430 Storage/DOSDrivers/PC0 86 1991/09/29 22:23:11 009433 Storage/DOSDrivers/AUX 896 1995/01/05 15:12:30 000014 Storage/DOSDrivers/CD0 537 1995/03/19 16:25:16 000017 Storage/DOSDrivers/CD0.info 1991/09/29 22:23:12 008629 Storage/Keymaps/ 459 1991/09/29 22:23:13 009435 Storage/Keymaps/f.info 1336 1991/09/29 22:23:14 009437 Storage/Keymaps/f, Franais 1992/09/02 12:40:47 008631 Storage/Monitors/ 356 1992/09/02 11:58:10 009438 Storage/Monitors/Euro36.info 356 1992/09/02 11:58:17 009440 Storage/Monitors/DblPAL.info 356 1992/09/02 11:58:11 009442 Storage/Monitors/Euro72.info 356 1992/09/02 11:58:13 009444 Storage/Monitors/Multiscan.info 356 1992/09/02 11:58:18 009446 Storage/Monitors/DblNTSC.info 356 1992/09/02 11:58:19 009448 Storage/Monitors/VGAOnly.info 356 1992/09/02 11:58:14 009450 Storage/Monitors/NTSC.info 356 1992/09/02 11:58:08 009452 Storage/Monitors/A2024.info 356 1992/09/02 11:58:17 009454 Storage/Monitors/Super72.info 6168 1992/09/02 11:51:33 009456 Storage/Monitors/NTSC 8796 1992/09/02 11:51:33 009457 Storage/Monitors/Euro72 8928 1992/09/02 11:51:33 009458 Storage/Monitors/Super72 8924 1992/09/02 11:51:33 009459 Storage/Monitors/Multiscan 9980 1992/09/02 11:51:33 009460 Storage/Monitors/DblNTSC 10664 1992/09/02 11:51:33 009461 Storage/Monitors/A2024 9900 1992/09/02 11:51:33 009462 Storage/Monitors/Euro36 3128 1992/09/02 11:51:33 009463 Storage/Monitors/VGAOnly 9972 1992/09/02 11:51:33 009464 Storage/Monitors/DblPAL 1996/10/31 22:07:24 008130 WBStartup/ 11396 1996/07/15 12:34:51 008133 WBStartup/StormScreenManager 643 1996/07/15 12:34:51 008157 WBStartup/StormScreenManager.info 10544 1996/10/27 19:54:44 002714 WBStartup/ZJWatch 628 1996/10/31 22:07:23 002736 WBStartup/.info 1829 1996/10/31 22:07:25 002739 WBStartup/ZJWatch.info 1997/01/04 18:20:04 008546 C/ 1712 1992/09/02 11:51:33 008634 C/Install 700 1992/09/02 11:51:33 008635 C/MakeLink 828 1992/09/02 11:51:33 008638 C/Status 1420 1992/09/02 11:51:33 008641 C/BindDrivers 3516 1992/09/02 11:51:33 008642 C/ConClip 5820 1996/10/14 22:04:23 008643 C/Ed 6880 1994/02/18 9:56:04 008644 C/Mount 2472 1992/09/02 11:51:33 008645 C/Search 1972 1992/09/02 11:51:33 008646 C/Delete 728 1992/09/02 11:51:33 008647 C/Avail 14792 1992/09/02 11:51:33 008650 C/Edit 1496 1992/09/02 11:51:33 008651 C/Type 444 1992/09/02 11:51:33 008652 C/AddBuffers 13484 1994/02/15 16:09:06 008654 C/SetPatch 432 1992/09/02 11:51:33 008655 C/Break 1412 1992/09/02 11:51:33 008657 C/SetKeyboard 584 1992/09/02 11:51:33 008658 C/Relabel 1200 1992/09/02 11:51:33 008661 C/Join 536 1992/09/02 11:51:33 008662 C/Lock 688 1992/09/02 11:51:33 008665 C/SetDate 1980 1992/09/02 11:51:33 008668 C/Info 1120 1992/09/02 11:51:33 008669 C/RequestChoice 896 1992/09/02 11:51:33 008670 C/Filenote 3220 1992/09/02 11:51:33 008673 C/Assign 3652 1992/09/02 11:51:33 008674 C/CPU 460 1992/09/02 11:51:33 008675 C/ChangeTaskPri 3440 1992/09/02 11:51:33 008677 C/Dir 1140 1992/09/02 11:51:33 008678 C/Rename 1520 1992/09/02 11:51:33 008679 C/RequestFile 1768 1992/09/02 11:51:33 008680 C/MagTape 1092 1992/09/02 11:51:33 008681 C/SetFont 312 1992/09/02 11:51:33 008682 C/DiskChange 1980 1992/09/02 11:51:33 008684 C/Sort 1128 1992/09/02 11:51:33 008685 C/RemRAD 4432 1992/09/02 11:51:33 008686 C/Execute 5496 1992/09/02 11:51:33 008687 C/Copy 5108 1992/09/02 11:51:33 008688 C/List 464 1992/09/02 11:51:33 008689 C/MakeDir 1068 1992/09/02 11:51:33 008691 C/Which 1092 1992/09/02 11:51:33 008692 C/Date 13164 1992/09/02 11:51:33 008693 C/IPrefs 1452 1992/09/02 11:51:33 008694 C/IconX 1136 1992/09/02 11:51:33 008695 C/LoadWB 5880 1992/09/02 11:51:33 008696 C/AddDataTypes 1276 1992/09/02 11:51:33 008697 C/Protect 668 1992/09/02 11:51:33 008698 C/SetClock 852 1992/09/02 11:51:33 008701 C/Wait 2084 1992/09/02 11:51:33 008704 C/Eval 4804 1992/09/02 11:51:33 008705 C/Version 20152 1995/04/10 23:07:41 009119 C/HighDensityPatch 4092 1995/08/29 14:06:06 010685 C/SquirrelSCSI 1444 1994/01/12 15:49:31 010027 C/SetPatchMrgCop 1992/09/02 12:45:12 008551 Prefs/ 617 1992/09/02 11:56:00 008706 Prefs/PrinterPS.info 617 1992/09/02 11:55:48 008709 Prefs/Input.info 632 1992/09/02 11:54:56 008712 Prefs/Presets.info 617 1992/09/02 11:55:46 008715 Prefs/IControl.info 628 1992/09/02 12:40:49 008718 Prefs/Printer.info 580 1992/09/02 11:55:53 008721 Prefs/Palette.info 580 1992/09/02 11:56:02 008724 Prefs/ScreenMode.info 587 1992/09/02 11:56:07 008727 Prefs/Time.info 617 1992/09/02 11:55:51 008730 Prefs/Overscan.info 617 1992/09/02 11:56:05 008733 Prefs/Sound.info 617 1992/09/02 11:55:58 008736 Prefs/PrinterGfx.info 633 1992/09/02 11:56:09 008739 Prefs/WBPattern.info 617 1992/09/02 11:55:45 008742 Prefs/Font.info 631 1992/09/02 11:55:55 008745 Prefs/Pointer.info 617 1992/09/02 11:55:49 008748 Prefs/Locale.info 628 1992/09/02 11:56:03 008751 Prefs/Serial.info 21688 1992/09/02 11:51:33 008754 Prefs/WBPattern 13720 1992/09/02 11:51:33 008755 Prefs/ScreenMode 10580 1992/09/02 11:51:33 008756 Prefs/IControl 1997/02/14 22:25:31 008757 Prefs/Env-Archive/ 1978/01/06 4:02:09 009467 Prefs/Env-Archive/ADPro/ 456 1978/02/08 1:01:04 009469 Prefs/Env-Archive/povpanel.prefs 39 1994/04/05 21:56:05 009471 Prefs/Env-Archive/xprzmodem 6 1992/09/02 12:41:44 009473 Prefs/Env-Archive/Kickstart 1996/01/25 22:30:09 009475 Prefs/Env-Archive/Sys/ 828 1994/08/04 16:19:26 009873 Prefs/Env-Archive/Sys/crossmac_def_disk.info, 000000000000000040000000000000000000000000000000000000000000000004 318 1993/08/08 22:12:29 009876 Prefs/Env-Archive/Sys/Pointer.prefs 62 1993/08/08 22:11:53 009878 Prefs/Env-Archive/Sys/icontrol.prefs 318 1993/08/08 22:12:43 009880 Prefs/Env-Archive/Sys/sound.prefs 518 1992/09/02 12:44:47 009882 Prefs/Env-Archive/Sys/font.prefs 162 1996/01/25 22:30:09 009885 Prefs/Env-Archive/Sys/printer.prefs 62 1992/09/02 12:42:06 009887 Prefs/Env-Archive/Sys/screenmode.prefs 72 1993/08/08 22:15:00 009889 Prefs/Env-Archive/Sys/printergfx.prefs 70 1993/08/08 22:13:01 009891 Prefs/Env-Archive/Sys/overscan.prefs 68 1997/09/29 16:12:17 009893 Prefs/Env-Archive/Sys/serial.prefs 54 1995/06/17 17:34:18 009895 Prefs/Env-Archive/Sys/wbconfig.prefs 314 1993/10/14 17:22:57 009897 Prefs/Env-Archive/Sys/WBPattern.prefs 78 1993/08/08 22:13:37 009899 Prefs/Env-Archive/Sys/input.prefs 894 1993/08/08 22:11:37 009901 Prefs/Env-Archive/Sys/locale.prefs 434 1992/09/02 12:44:31 009904 Prefs/Env-Archive/Sys/palette.prefs 5 1992/09/02 12:41:44 009478 Prefs/Env-Archive/Workbench 52 1992/09/02 13:40:54 009480 Prefs/Env-Archive/DOpus_format.prefs 4 1993/05/29 10:46:34 009484 Prefs/Env-Archive/space 352 1992/09/02 13:39:10 009486 Prefs/Env-Archive/DOpus_print.prefs 72 1992/09/02 12:49:32 009488 Prefs/Env-Archive/ShowVIC.prefs 25 1992/09/02 12:57:15 009490 Prefs/Env-Archive/PcRestore.prefs 68 1995/11/27 17:47:33 009482 Prefs/Env-Archive/ZOOMOPTS 206 1997/02/14 22:25:31 009465 Prefs/Env-Archive/ASM-One.Pref 1996/01/17 18:32:08 009492 Prefs/Env-Archive/sc/ 85 1996/01/17 18:32:08 003189 Prefs/Env-Archive/sc/SCOPTIONS 1994/06/01 22:35:24 009494 Prefs/Env-Archive/SmartPlay/ 878 1994/06/01 22:35:24 009906 Prefs/Env-Archive/SmartPlay/SmartPlay.Config 1994/01/11 21:55:48 009496 Prefs/Env-Archive/UIK/ 1994/01/11 21:55:48 009909 Prefs/Env-Archive/UIK/Objects/ 1994/02/08 17:41:06 009498 Prefs/Env-Archive/GadToolsBox/ 50 1994/05/17 3:33:41 009500 Prefs/Env-Archive/TERMWINDOW 270 1978/01/05 4:01:15 009502 Prefs/Env-Archive/AmiTEL.prefs 1994/06/03 9:42:47 009504 Prefs/Env-Archive/Upcat/ 166 1994/06/03 9:42:47 009911 Prefs/Env-Archive/Upcat/Upcat.prefs 1995/11/15 21:52:52 009506 Prefs/Env-Archive/ADOpus/ 18 1995/11/15 21:52:52 009913 Prefs/Env-Archive/ADOpus/adopus.cfg 35 1995/11/15 21:52:52 009915 Prefs/Env-Archive/ADOpus/ImageDex.cfg 181 1995/02/06 9:05:31 009508 Prefs/Env-Archive/MultiPlayerPrefs 1996/10/09 22:18:35 007976 Prefs/Env-Archive/APlayer/ 1995/03/22 18:31:33 007982 Prefs/Env-Archive/APlayer/Players/ 1996/10/09 22:18:35 000232 Prefs/Env-Archive/APlayer/NotePlayers/ 1996/10/09 22:18:35 000238 Prefs/Env-Archive/APlayer/Agents/ 1995/06/05 18:18:08 007907 Prefs/Env-Archive/MusicManII/ 185 1995/06/05 18:18:08 007913 Prefs/Env-Archive/MusicManII/MusicManII.Prefs 24 1995/07/06 12:20:10 010454 Prefs/Env-Archive/PlaySID.prefs 1996/10/21 20:54:23 003860 Prefs/Env-Archive/AmigaGuide/ 10 1998/05/27 22:54:16 003863 Prefs/Env-Archive/AmigaGuide/Path 1996/05/15 21:00:25 002956 Prefs/Env-Archive/MusicManIII/ 819 1996/05/15 21:00:25 002959 Prefs/Env-Archive/MusicManIII/MusicManIII.Prefs 1996/10/21 21:33:17 008160 Prefs/Env-Archive/STORMCPP/ 571 1996/10/21 21:33:05 008167 Prefs/Env-Archive/STORMCPP/def_project.info 876 1996/10/21 21:33:05 008169 Prefs/Env-Archive/STORMCPP/def_text.c.info 876 1996/10/21 21:33:05 008172 Prefs/Env-Archive/STORMCPP/def_text.cc.info 861 1996/10/21 21:33:05 008175 Prefs/Env-Archive/STORMCPP/def_text.cpp.info 864 1996/10/21 21:33:06 008178 Prefs/Env-Archive/STORMCPP/def_text.h.info 861 1996/10/21 21:33:05 008181 Prefs/Env-Archive/STORMCPP/def_text.info 504 1996/10/21 21:33:17 008184 Prefs/Env-Archive/STORMCPP/def_librarian.info 628 1996/10/21 21:11:49 008164 Prefs/Env-Archive/STORMCPP.info 27 1996/10/31 22:08:29 002822 Prefs/Env-Archive/ZJTools.prefs 733 1997/07/10 22:30:40 010085 Prefs/Env-Archive/VirusZ_II.Prefs 12 1997/07/10 22:30:40 010219 Prefs/Env-Archive/VirusZ_II.Archivers 27 1998/04/23 19:29:13 005474 Prefs/Env-Archive/DELICONFIG 12076 1992/09/02 11:51:33 008760 Prefs/Printer 10852 1992/09/02 11:51:33 008761 Prefs/Serial 14352 1992/09/02 11:51:33 008762 Prefs/PrinterGfx 22720 1992/09/02 11:51:33 008763 Prefs/Locale 24972 1992/09/02 11:51:33 008764 Prefs/Palette 11440 1992/09/02 11:51:33 008765 Prefs/Font 13028 1992/09/02 11:51:33 008766 Prefs/Time 25268 1992/09/02 11:51:33 008767 Prefs/Pointer 12652 1992/09/02 11:51:33 008768 Prefs/Sound 18500 1992/09/02 11:51:33 008769 Prefs/Overscan 13796 1992/09/02 11:51:33 008770 Prefs/Input 1997/06/11 22:49:03 008771 Prefs/Env/ 1978/01/06 4:02:09 009510 Prefs/Env/ADPro/ 456 1978/02/08 1:01:04 009512 Prefs/Env/povpanel.prefs 39 1994/04/05 21:56:05 009514 Prefs/Env/xprzmodem 270 1978/01/05 4:01:15 009516 Prefs/Env/AmiTEL.prefs 6 1998/10/03 13:34:54 009518 Prefs/Env/Kickstart 1997/05/05 20:27:36 009520 Prefs/Env/Sys/ 828 1994/08/04 16:19:26 009917 Prefs/Env/Sys/crossmac_def_disk.info, 000000000000000040000000000000000000000000000000000000000000000004 318 1993/08/08 22:12:29 009920 Prefs/Env/Sys/Pointer.prefs 62 1993/08/08 22:11:53 009922 Prefs/Env/Sys/icontrol.prefs 318 1994/01/27 19:14:38 009924 Prefs/Env/Sys/sound.prefs 518 1995/11/27 22:48:19 009926 Prefs/Env/Sys/font.prefs 162 1997/10/05 15:20:34 009929 Prefs/Env/Sys/printer.prefs 62 1997/05/05 20:27:36 009931 Prefs/Env/Sys/screenmode.prefs 72 1993/08/08 22:15:00 009933 Prefs/Env/Sys/printergfx.prefs 70 1993/08/08 22:13:01 009935 Prefs/Env/Sys/overscan.prefs 68 1997/09/29 16:12:18 009937 Prefs/Env/Sys/serial.prefs 54 1992/09/02 11:51:33 009939 Prefs/Env/Sys/wbconfig.prefs 314 1978/01/11 2:12:39 009941 Prefs/Env/Sys/WBPattern.prefs 78 1996/02/15 19:26:35 009943 Prefs/Env/Sys/input.prefs 894 1993/08/08 22:11:37 009945 Prefs/Env/Sys/locale.prefs 434 1992/09/02 12:44:32 009948 Prefs/Env/Sys/palette.prefs 5 1998/10/03 13:34:53 009523 Prefs/Env/Workbench 52 1993/11/29 22:36:07 009525 Prefs/Env/DOpus_format.prefs 4 1993/05/29 10:46:34 009529 Prefs/Env/space 352 1992/09/02 13:39:10 009531 Prefs/Env/DOpus_print.prefs 72 1992/09/02 12:49:32 009533 Prefs/Env/ShowVIC.prefs 1997/06/07 17:31:58 009535 Prefs/Env/sc/ 85 1996/01/17 18:32:08 009950 Prefs/Env/sc/SCOPTIONS 11 1998/06/10 20:15:33 009952 Prefs/Env/sc/projdir 1996/02/07 22:28:00 009537 Prefs/Env/ImageFX/ 4 1994/02/02 19:33:57 009954 Prefs/Env/ImageFX/VMEM_Index 3 1992/09/02 12:49:11 009956 Prefs/Env/ImageFX/JPEG_Quality 4 1996/02/07 22:28:00 009958 Prefs/Env/ImageFX/ANIM_Frame 2 1996/10/21 21:43:40 010458 Prefs/Env/ImageFX/JPEG_Smoothing 68 1995/11/27 17:47:33 009527 Prefs/Env/ZOOMOPTS 5 1994/01/06 23:25:03 009539 Prefs/Env/TERM 6 1994/01/06 23:25:03 009541 Prefs/Env/LESSCHARSET 1994/06/01 22:35:24 009543 Prefs/Env/SmartPlay/ 878 1994/06/01 22:35:24 009960 Prefs/Env/SmartPlay/SmartPlay.Config 1994/01/11 21:55:51 009545 Prefs/Env/UIK/ 1994/01/11 21:55:47 009963 Prefs/Env/UIK/Objects/ 158 1994/01/11 21:55:51 009965 Prefs/Env/UIK/uik.prefs 1994/02/08 17:41:06 009547 Prefs/Env/GadToolsBox/ 50 1994/05/17 3:33:44 009549 Prefs/Env/TERMWINDOW 1994/02/22 17:18:29 009551 Prefs/Env/Designer/ 276 1994/02/22 17:18:29 009967 Prefs/Env/Designer/Designer.Prefs 88 1994/07/06 19:48:35 009553 Prefs/Env/Trackdisk.prefs 1994/06/03 9:42:46 009555 Prefs/Env/Upcat/ 166 1994/06/03 9:42:46 009969 Prefs/Env/Upcat/Upcat.prefs 181 1995/02/06 9:05:31 009557 Prefs/Env/MultiPlayerPrefs 1995/03/15 19:21:50 001826 Prefs/Env/xMore/ 269 1994/04/11 0:12:02 001829 Prefs/Env/xMore/xMore 824 1994/04/11 0:10:50 001834 Prefs/Env/xMore/MAC.cvt 597 1994/01/23 20:22:10 001837 Prefs/Env/xMore/keys 30 1994/04/10 7:00:22 001840 Prefs/Env/xMore/convert 760 1995/03/15 19:21:50 001831 Prefs/Env/xMore/MSDOS.cvt 1996/10/09 22:18:35 007979 Prefs/Env/APlayer/ 1995/03/22 18:31:33 007985 Prefs/Env/APlayer/Players/ 1464 1995/06/20 10:07:02 007988 Prefs/Env/APlayer/APlayer.prefs 32 1995/06/20 10:07:02 007992 Prefs/Env/APlayer/APlayer.libs 1996/10/09 22:18:35 000229 Prefs/Env/APlayer/NotePlayers/ 1996/10/09 22:18:35 000235 Prefs/Env/APlayer/Agents/ 0 1995/06/01 23:55:04 010067 Prefs/Env/dopus 1995/06/05 18:18:08 007910 Prefs/Env/MusicManII/ 185 1995/06/05 18:18:08 007915 Prefs/Env/MusicManII/MusicManII.Prefs 1996/10/31 21:44:54 003855 Prefs/Env/AmigaGuide/ 10 1998/05/27 22:54:16 010567 Prefs/Env/AmigaGuide/Path 1997/06/02 21:47:02 010420 Prefs/Env/mui/ 24 1995/11/09 16:55:09 010426 Prefs/Env/mui/Global.prefs 24 1995/11/09 16:55:09 010429 Prefs/Env/mui/AmigaMosaic.prefs 80 1995/11/09 17:10:53 010431 Prefs/Env/mui/AMOSAIC.1.wini 24 1995/11/23 22:20:47 003183 Prefs/Env/mui/X-Wins.prefs 160 1995/11/23 22:23:30 003185 Prefs/Env/mui/X-WINS.1.wini 120 1995/11/23 22:21:17 003187 Prefs/Env/mui/X-WINS.1.cfg 24 1995/11/30 23:25:06 003233 Prefs/Env/mui/Xfig.prefs 90 1997/05/05 19:47:34 014907 Prefs/Env/mui/MUI.prefs 138 1997/05/05 20:11:37 014909 Prefs/Env/mui/PSI.1.prefs 1118 1997/05/05 20:09:56 014911 Prefs/Env/mui/PublicScreens.iff 530 1998/07/09 21:02:37 014915 Prefs/Env/mui/IBROWSE.prefs 186 1997/06/02 21:47:03 010467 Prefs/Env/mui/VOYAGER.prefs 7 1995/12/13 18:02:02 003290 Prefs/Env/wwDriver 1 1995/12/13 18:01:58 003292 Prefs/Env/wwTop 4 1995/12/13 18:01:58 003294 Prefs/Env/wwBottom 4 1995/12/13 18:01:58 003296 Prefs/Env/wwLeft 4 1995/12/13 18:01:58 003298 Prefs/Env/wwRight 1996/05/15 21:00:25 010424 Prefs/Env/MusicManIII/ 819 1996/05/15 21:00:25 002962 Prefs/Env/MusicManIII/MusicManIII.Prefs 6 1996/10/09 20:30:44 001184 Prefs/Env/SCSI-Install-PROCESSOR 2 1996/10/14 22:05:08 000707 Prefs/Env/GOLDEDINSTALL 1996/10/21 21:33:04 008186 Prefs/Env/STORMCPP/ 571 1996/10/21 21:33:03 008192 Prefs/Env/STORMCPP/def_project.info 876 1996/10/21 21:33:04 008194 Prefs/Env/STORMCPP/def_text.c.info 876 1996/10/21 21:33:04 008197 Prefs/Env/STORMCPP/def_text.cc.info 861 1996/10/21 21:33:04 008200 Prefs/Env/STORMCPP/def_text.cpp.info 864 1996/10/21 21:33:04 008203 Prefs/Env/STORMCPP/def_text.h.info 861 1996/10/21 21:33:03 008206 Prefs/Env/STORMCPP/def_text.info 483 1996/01/25 11:32:30 008209 Prefs/Env/STORMCPP/def_librarian.info 628 1996/10/21 21:11:51 008189 Prefs/Env/STORMCPP.info 1996/12/03 20:56:40 000878 Prefs/Env/AMIS/ 11594 1996/12/03 20:56:40 000881 Prefs/Env/AMIS/AMIS.prefs 6 1996/12/31 15:59:10 001205 Prefs/Env/DIS64 27 1996/10/31 22:08:29 002820 Prefs/Env/ZJTools.prefs 1 1997/01/04 18:49:28 010086 Prefs/Env/PPaintLanguage 4 1997/01/04 18:49:31 010088 Prefs/Env/PPSysInstaller 7 1998/10/03 13:34:55 011348 Prefs/Env/Language 27 1998/04/23 19:29:13 005472 Prefs/Env/DELICONFIG 22936 1992/09/02 11:51:33 008774 Prefs/PrinterPS 1994/11/15 22:06:12 008555 System/ 454 1994/11/15 22:06:12 008775 System/DiskCopy.info 927 1997/08/17 23:07:51 008777 System/Shell.info 454 1992/09/02 11:53:52 008780 System/FixFonts.info 486 1992/09/02 11:53:54 008782 System/NoFastMem.info 533 1992/09/02 11:56:11 008784 System/Intellifont.info 468 1992/09/02 11:53:55 008787 System/RexxMast.info 454 1992/09/02 11:53:53 008789 System/Format.info 12896 1992/09/02 11:51:33 008791 System/Format 68916 1992/09/02 11:51:33 008792 System/Intellifont 1180 1992/09/02 11:51:33 008793 System/CLI 9816 1994/07/11 18:08:02 008794 System/DiskCopy 840 1992/09/02 11:51:33 008795 System/FixFonts 524 1992/09/02 11:51:33 008798 System/NoFastMem 2364 1992/09/02 11:51:33 008801 System/RexxMast 1994/07/25 19:38:02 008802 System/old/ 482 1978/01/01 0:26:48 009559 System/old/FastMemFirst.info 374 1992/09/02 14:01:05 009561 System/old/MergeMem.info 434 1978/01/01 0:26:47 009563 System/old/SlowMemLast.info 976 1978/01/01 0:10:40 009565 System/old/FastMemFirst 2524 1978/01/01 0:10:44 009568 System/old/MergeMem 1628 1978/01/01 0:07:46 009569 System/old/SlowMemLast 1996/10/09 20:33:19 008558 L/ 628 1994/11/15 22:05:58 008804 L/FileSystem_Trans.info 1364 1992/09/02 11:51:33 008807 L/port-handler 13892 1994/01/05 22:15:10 008808 L/PowerSnap-handler 1994/11/15 21:55:20 008809 L/FileSystem_Trans/ 512 1992/09/02 11:51:33 009570 L/FileSystem_Trans/INTL.crossdos 512 1992/09/02 11:51:33 009572 L/FileSystem_Trans/DANSK.crossdos 2980 1994/08/17 15:29:08 009574 L/FileSystem_Trans/ftypeDB.mac 2392 1992/09/02 11:51:33 008811 L/aux-handler 2664 1992/09/02 11:51:33 008812 L/queue-handler 25184 1992/09/02 11:51:33 008813 L/CrossDOSFileSystem 64 1993/02/01 21:59:44 008814 L/LhA.key 3602 1993/08/12 22:02:46 008816 L/Bootblock.brainfile 2964 1993/08/22 23:02:46 008817 L/ixpipe-handler 5360 1992/12/25 13:46:16 008818 L/prospool-handler 17676 1995/04/24 18:26:56 008312 L/CDFileSystem 40552 1993/12/15 2:27:46 008819 L/KingCON-handler.020, Optimized version for MC68020 and better 40552 1993/12/15 2:27:46 008820 L/KingCON-handler, Optimized version for MC68020 and better 69408 1994/09/15 14:36:08 008821 L/CrossMACFileSystem 27980 1994/04/21 0:49:02 008822 L/ProfFileSystem 24420 1992/09/08 12:16:33 010596 L/FastFileSystem 1997/03/19 20:03:42 008561 Devs/ 632 1992/09/02 11:54:45 008823 Devs/Monitors.info 632 1992/09/02 11:54:46 008826 Devs/Printers.info 632 1992/09/02 11:54:44 008829 Devs/DOSDrivers.info 632 1993/08/08 22:18:44 008832 Devs/DataTypes.info 632 1992/09/02 11:54:46 008835 Devs/Keymaps.info 16192 1994/09/12 10:23:38 008838 Devs/mfm.device 1996/10/12 8:50:18 008839 Devs/DOSDrivers/ 481 1996/10/11 20:46:18 009575 Devs/DOSDrivers/MAC0.info 481 1994/11/15 22:06:06 009577 Devs/DOSDrivers/MAC1.info 481 1994/11/15 22:06:07 009579 Devs/DOSDrivers/MAC2.info 481 1994/11/15 22:06:07 009581 Devs/DOSDrivers/MAC3.info 481 1992/09/02 11:54:42 009583 Devs/DOSDrivers/PIPE.info 492 1995/04/03 21:10:08 009585 Devs/DOSDrivers/PC1.info 466 1996/10/11 20:46:13 009587 Devs/DOSDrivers/DS1.info 481 1996/10/11 20:46:09 009589 Devs/DOSDrivers/PF1.info 312 1994/04/25 12:37:36 009591 Devs/DOSDrivers/MAC0 312 1994/04/25 12:37:46 009593 Devs/DOSDrivers/MAC1 312 1994/04/25 12:37:50 009595 Devs/DOSDrivers/MAC2 312 1994/04/25 12:37:58 009597 Devs/DOSDrivers/MAC3 670 1995/04/03 21:10:08 009599 Devs/DOSDrivers/PC1 104 1992/09/02 11:51:33 009602 Devs/DOSDrivers/PIPE 288 1994/10/18 21:37:31 009604 Devs/DOSDrivers/DS0 664 1995/04/03 21:10:08 009606 Devs/DOSDrivers/PC0 288 1994/05/01 15:19:54 009609 Devs/DOSDrivers/DS1 322 1993/11/18 15:24:22 009611 Devs/DOSDrivers/PF1 666 1994/01/29 18:18:36 002866 Devs/DOSDrivers/SD0 554 1995/01/17 20:10:29 002869 Devs/DOSDrivers/SD0.info 666 1994/01/29 18:18:36 002872 Devs/DOSDrivers/SD1 554 1995/01/17 20:20:56 002875 Devs/DOSDrivers/SD1.info 492 1995/04/03 21:10:08 009865 Devs/DOSDrivers/PC0.info 373 1996/10/11 22:15:07 000277 Devs/DOSDrivers/ZIPC 1597 1996/10/11 20:45:58 000279 Devs/DOSDrivers/ZIPC.info 453 1996/10/11 22:27:39 000692 Devs/DOSDrivers/ZIPPC 1597 1996/10/11 20:45:58 000693 Devs/DOSDrivers/ZIPPC.info 5412 1992/09/02 11:51:33 008842 Devs/serial.device 1992/09/02 12:40:19 008843 Devs/Keymaps/ 1336 1992/09/02 11:51:33 009613 Devs/Keymaps/f, Franais 1328 1992/09/02 11:51:33 009614 Devs/Keymaps/gb, British 5014 1992/09/02 11:51:33 008845 Devs/postscript_init.ps 4272 1992/09/02 11:51:33 008846 Devs/parallel.device 1997/02/10 19:20:02 008847 Devs/DataTypes/ 467 1993/02/06 0:57:34 009615 Devs/DataTypes/PCX.info 473 1992/09/02 11:54:53 009617 Devs/DataTypes/AmigaGuide.info 473 1992/09/02 11:54:55 009619 Devs/DataTypes/ILBM.info 467 1993/07/29 20:33:06 009621 Devs/DataTypes/JPEG.info 473 1992/09/02 11:54:52 009623 Devs/DataTypes/8SVX.info 473 1992/09/02 11:54:54 009625 Devs/DataTypes/FTXT.info 467 1993/07/28 4:38:02 009627 Devs/DataTypes/GIF.info 98 1993/09/28 15:42:08 009629 Devs/DataTypes/PCX 114 1992/09/02 11:51:33 009631 Devs/DataTypes/AmigaGuide 88 1993/07/28 4:38:02 009633 Devs/DataTypes/gif 102 1992/09/02 11:51:33 009635 Devs/DataTypes/ILBM 102 1992/09/02 11:51:33 009637 Devs/DataTypes/8SVX 102 1992/09/02 11:51:33 009639 Devs/DataTypes/FTXT 98 1993/07/29 20:33:06 009641 Devs/DataTypes/JPEG 110 1995/09/30 16:17:02 004684 Devs/DataTypes/SVG 336 1993/09/28 15:42:08 009643 Devs/DataTypes/MacPaint 104 1993/09/28 15:42:08 009645 Devs/DataTypes/Windows Bitmap 108 1993/09/28 15:42:08 009647 Devs/DataTypes/Windows Icon 106 1994/06/14 15:06:12 003554 Devs/DataTypes/REKO Cardset 1533 1995/01/22 13:52:22 003556 Devs/DataTypes/REKO Cardset.info 96 1994/06/13 20:31:38 003578 Devs/DataTypes/Sun Raster 1533 1995/01/21 16:16:22 003580 Devs/DataTypes/Sun Raster.info 100 1995/03/12 9:42:24 010740 Devs/DataTypes/C++-Source 467 1995/03/12 9:42:24 010742 Devs/DataTypes/C++-Source.info 88 1995/03/12 9:39:00 010744 Devs/DataTypes/C-Source 467 1995/03/12 9:39:00 010746 Devs/DataTypes/C-Source.info 467 1995/09/30 16:17:02 004686 Devs/DataTypes/SVG.info 86 1994/10/30 15:58:24 002350 Devs/DataTypes/Targa 1527 1995/01/22 13:38:20 002352 Devs/DataTypes/Targa.info 86 1996/11/01 13:48:02 015168 Devs/DataTypes/PNG 467 1996/11/01 13:48:02 015170 Devs/DataTypes/PNG.info 108 1996/05/21 12:08:06 002978 Devs/DataTypes/ZX 473 1996/05/17 21:47:20 002980 Devs/DataTypes/ZX.info 102 1995/04/22 11:44:16 015323 Devs/DataTypes/Bitmap Font 467 1995/04/22 14:28:46 015325 Devs/DataTypes/Bitmap Font.info 102 1995/04/22 11:44:18 015327 Devs/DataTypes/Outline Font 467 1995/04/22 14:28:46 015329 Devs/DataTypes/Outline Font.info 238 1995/03/15 19:19:18 001169 Devs/DataTypes/DeBox 1574 1994/10/04 12:19:52 001171 Devs/DataTypes/DeBox.info 1997/03/19 20:03:42 011350 Devs/AHI/ 3424 1991/05/02 17:04:06 011353 Devs/AHI/wavetools.audio 3900 1991/05/02 17:04:06 011361 Devs/AHI/toccata.audio 5948 1991/05/02 17:04:08 011391 Devs/AHI/paula.audio 6412 1991/05/02 17:04:06 011404 Devs/AHI/filesave.audio 5056 1991/05/02 17:04:06 011518 Devs/AHI/delfina.audio 6944 1992/09/02 11:51:33 008850 Devs/clipboard.device 1992/09/02 12:40:47 008851 Devs/Monitors/ 356 1992/09/02 11:58:15 009649 Devs/Monitors/PAL.info 6156 1992/09/02 11:51:33 009651 Devs/Monitors/PAL 27420 1992/09/02 11:51:33 008853 Devs/printer.device 1996/10/21 20:48:53 008854 Devs/Printers/ 459 1992/09/02 11:58:40 009652 Devs/Printers/EpsonQ.info 459 1992/09/02 11:54:44 009654 Devs/Printers/Generic.info 459 1992/09/02 11:58:41 009656 Devs/Printers/EpsonXOld.info 459 1992/09/02 11:58:40 009658 Devs/Printers/EpsonX.info 6480 1992/09/02 13:52:56 009660 Devs/Printers/EpsonQ 7160 1992/09/02 11:51:33 009661 Devs/Printers/EpsonX 1084 1992/09/02 11:51:33 009662 Devs/Printers/Generic 4712 1992/09/02 11:51:33 009663 Devs/Printers/EpsonXOld 6684 1992/09/02 11:51:33 008856 Devs/mfm38_5.device 1997/06/11 20:02:29 008857 Devs/clipboards/ 454 1995/09/18 13:15:40 009666 Devs/clipboards/1 92 1998/10/03 14:01:30 009664 Devs/clipboards/0 9 1996/12/03 21:00:11 001158 Devs/clipboards/awebed.clip 3972 1992/11/22 18:48:54 008859 Devs/BaudBandit.device 232 1992/09/02 11:51:33 008860 Devs/system-configuration 617 1993/12/15 2:37:40 008862 Devs/KingCON-mountlist, Mountlist-entries for KCON and KRAW. 5124 1993/04/18 19:11:08 008865 Devs/artser.device 5548 1994/05/01 15:19:48 008866 Devs/diskspare.device 2480 1994/08/31 16:37:28 002859 Devs/statram.device 16192 1994/09/12 10:23:38 010064 Devs/mfm.device4140 8256 1995/08/24 12:28:20 010667 Devs/squirrelscsi.device 6460 1990/07/28 14:24:44 010100 Devs/CloantoAudio 1997/03/19 20:03:42 014725 Devs/AudioModes/ 624 1991/05/02 17:04:08 014728 Devs/AudioModes/WAVETOOLS 612 1991/05/02 17:04:08 014807 Devs/AudioModes/TOCCATA 1484 1991/05/02 17:04:08 014810 Devs/AudioModes/PAULA 556 1991/05/02 17:04:08 014814 Devs/AudioModes/FILESAVE 612 1991/05/02 17:04:08 014817 Devs/AudioModes/DELFINA 26484 1991/05/02 17:04:06 014820 Devs/ahi.device 1996/10/31 22:07:13 008564 Tools/ 1309 1992/09/02 12:40:50 008867 Tools/IconEdit.info 826 1992/09/02 11:55:32 008871 Tools/InitPrinter.info 632 1992/09/02 11:55:24 008874 Tools/Commodities.info 450 1992/09/02 11:55:34 008877 Tools/Lacer.info 470 1992/09/02 11:55:36 008879 Tools/MEmacs.info 515 1992/09/02 11:55:29 008881 Tools/GraphicDump.info 470 1992/09/02 11:55:33 008884 Tools/KeyShow.info 1224 1992/09/02 11:57:04 008886 Tools/HDBackup.info 579 1992/09/02 11:55:25 008890 Tools/Calculator.info 450 1992/09/02 11:55:41 008893 Tools/ShowConfig.info 485 1992/09/02 11:55:39 008895 Tools/PrintFiles.info 563 1992/09/02 11:55:26 008897 Tools/CMD.info 826 1992/09/02 11:56:57 008900 Tools/HDToolBox.info 454 1992/09/02 11:55:38 008903 Tools/PrepCard.info 1992/09/02 13:08:38 008905 Tools/Commodities/ 578 1992/09/02 12:40:50 009668 Tools/Commodities/ClickToFront.info 557 1992/09/02 13:08:38 009671 Tools/Commodities/CrossDOS.info 502 1992/09/02 11:55:14 009674 Tools/Commodities/AutoPoint.info 531 1992/09/02 12:40:51 009676 Tools/Commodities/Exchange.info 597 1992/09/02 12:40:50 009679 Tools/Commodities/Blanker.info 502 1992/09/02 11:55:22 009682 Tools/Commodities/NoCapsLock.info 502 1992/09/02 11:55:22 009684 Tools/Commodities/MouseBlanker.info 544 1992/09/02 12:40:51 009686 Tools/Commodities/FKey.info 2788 1992/09/02 11:51:33 009689 Tools/Commodities/NoCapsLock 6780 1992/09/02 11:51:33 009690 Tools/Commodities/Exchange 3112 1992/09/02 11:51:33 009691 Tools/Commodities/AutoPoint 3028 1992/09/02 11:51:33 009692 Tools/Commodities/MouseBlanker 8952 1992/09/02 11:51:33 009693 Tools/Commodities/CrossDOS 10208 1992/09/02 11:51:33 009694 Tools/Commodities/FKey 10232 1992/09/02 11:51:33 009695 Tools/Commodities/Blanker 3792 1992/09/02 11:51:33 009696 Tools/Commodities/ClickToFront 2988 1992/09/02 11:51:33 008908 Tools/GraphicDump 46144 1992/09/02 11:51:33 008909 Tools/IconEdit 21156 1992/09/02 11:51:33 008910 Tools/PrepCard 101832 1992/09/02 11:51:33 008911 Tools/BRU 10684 1992/09/02 11:51:33 008912 Tools/KeyShow 11928 1992/09/02 11:51:33 008913 Tools/ShowConfig 83248 1992/09/02 11:51:33 008914 Tools/HDBackup 296 1992/09/02 11:51:33 008915 Tools/InitPrinter 10580 1992/09/02 11:51:33 008917 Tools/Calculator 7688 1992/09/02 11:51:33 008918 Tools/CMD 296 1992/09/02 11:51:33 008919 Tools/Lacer 52484 1992/09/02 11:51:33 008921 Tools/MEmacs 2196 1992/09/02 11:51:33 008922 Tools/PrintFiles 97144 1992/09/02 11:51:33 008923 Tools/HDToolBox 11573 1992/09/02 11:51:33 008924 Tools/HDBackup.help 1592 1995/03/27 10:16:40 010659 Tools/SquirrelHDToolBox 928 1996/10/12 8:26:25 010664 Tools/SquirrelHDToolBox.info 2254 1996/10/19 17:49:14 000266 Tools/drive definitions 1996/10/31 22:07:30 002684 Tools/ZJTools/ 6852 1996/09/18 10:33:26 002694 Tools/ZJTools/ZJTool 1761 1996/09/17 15:37:40 002709 Tools/ZJTools/ZJTool.info 1996/10/31 22:07:25 002744 Tools/ZJTools/Icons/ 876 1996/10/31 22:07:25 002747 Tools/ZJTools/Icons/Eject.info 32656 1996/10/27 19:50:26 002750 Tools/ZJTools/ZJTools.guide 1857 1996/09/12 20:22:16 002815 Tools/ZJTools/ZJTools.guide.info 2785 1996/10/31 22:07:13 002687 Tools/ZJTools.info 1997/06/08 19:35:23 008568 S/ 460 1978/01/06 22:27:11 008925 S/BB.Config.info 300 1997/08/24 19:17:54 008930 S/Pro-Wizard.prefs 1559 1992/09/02 11:51:33 008932 S/HDBackup.config 268 1993/03/31 19:52:49 008933 S/jed.config 615 1992/09/02 11:51:33 008940 S/Ed-startup 709 1992/09/02 11:51:33 008943 S/DPat 2980 1978/01/06 22:27:10 008946 S/BB.Config 10 1993/10/11 19:34:45 008947 S/fontlist.pp 1764 1991/07/21 18:15:07 008949 S/classx.sh 822 1995/07/04 9:29:01 008937 S/genielist.pp 107 1997/06/08 19:33:37 008935 S/PPage.DFLT 830 1997/06/08 19:33:40 008950 S/prevfiles.pp 1281 1997/07/03 20:39:54 010138 S/Startup-Sequence 1843 1992/09/02 11:51:33 008953 S/BRUtab 156 1995/09/14 13:23:41 008956 S/Moor.cfg 1051 1994/02/24 14:27:39 008959 S/classes 248 1992/09/02 11:51:33 008960 S/PCD 487 1994/07/25 20:04:48 008962 S/PPage.ini 283 1992/09/02 11:51:33 008964 S/SPat 48 1994/01/13 13:53:07 008966 S/MineSweeper.highscores 2652 1992/02/29 15:45:34 008968 S/Default.iimcr.old 2652 1992/02/29 15:45:34 008969 S/Default.immcr.old 2652 1992/02/29 15:45:34 008970 S/Default.ipmcr.old 4 1997/06/08 19:31:00 008954 S/fontsize.pp 2261 1997/06/08 19:35:22 010062 S/.cshrc 1388 1998/06/11 20:50:41 003401 S/user-startup 6 1992/02/29 15:45:32 008972 S/picmdpath 2652 1992/02/29 15:45:34 008974 S/Default.iimcr 2652 1992/02/29 15:45:34 008979 S/Default.immcr 2652 1992/02/29 15:45:34 008980 S/Default.ipmcr 1995/06/12 23:53:55 009032 S/scan/ 0 1995/06/12 23:51:56 010091 S/scan/scan810000.log 2009 1995/06/12 23:53:55 010092 S/scan/scan810000.bmap 43916 1995/09/26 22:18:24 004595 S/HippoPlayer.group 1163 1995/11/09 17:10:53 001089 S/mosaic-global-history 20 1995/12/13 17:52:55 015388 S/TurboCalc.LRU 2709 1995/12/30 16:55:40 003316 S/ncomm.key 721 1996/10/12 22:01:23 000241 S/aliases 1592 1996/08/15 13:16:06 002576 S/PT.config-00 628 1996/10/21 21:53:10 002582 S/.info 6489 1998/06/02 22:04:01 008609 S/Startup.DM 17872 1992/03/14 19:12:42 008992 S/PageGenie.pgen 1238 1993/01/28 18:30:32 008994 S/PPageGenie.hlp 2337 1993/10/21 15:39:44 009002 S/PPageFilters.dflt 473 1993/11/17 22:33:32 009003 S/Startup.supdup 62 1994/02/28 23:45:41 009005 S/DT.config 1000 1994/01/11 21:57:08 009007 S/poing.scores 142 1978/01/01 10:49:19 009011 S/.login 1592 1996/07/11 14:39:30 002594 S/PT.config-01 36 1996/12/02 22:30:08 000876 S/DCTV-Viewer.prefs 460 1997/03/23 22:10:02 011346 S/Startup.DM.info 366 1978/01/01 23:52:41 009013 S/BB.Phone 112 1992/08/27 15:33:39 009015 S/serial-number 116 1978/01/20 2:57:22 009017 S/SigMaker.config 3374 1994/01/01 14:15:58 009019 S/mplot.prefs 5 1994/02/23 19:25:18 009020 S/PrtSc.cfg 804 1994/06/13 17:57:41 009022 S/RexxCommands 0 1978/02/07 23:57:47 009025 S/DIAne.Defaults 412 1994/09/09 17:28:27 009033 S/P60A.prefs 108 1994/03/30 18:55:58 009035 S/Compile.ced 94 1994/03/30 18:56:14 009037 S/Make.ced 724 1994/03/30 18:56:18 009039 S/NextError.ced 82812 1994/12/25 3:25:08 009115 S/Pro-Wizard.reco 2574 1996/10/09 22:16:04 007799 S/HippoPlayer.prefs 31 1995/06/12 23:53:55 010097 S/scan.defs 1997/06/11 22:53:53 008580 T/ 1271 1990/08/31 10:36:59 009116 T/TxEd.Backup 156 1994/05/31 20:35:47 009120 T/JBPQ.0001 1 1994/03/09 18:24:58 009122 T/CshCounter 264 1994/06/23 22:11:40 009124 T/5ZVW.0000 156 1994/05/31 20:00:14 009128 T/JBPQ.0000 264 1994/06/26 12:27:06 009130 T/5IC0.0000 156 1994/07/30 21:48:35 009132 T/RVSY.0000 264 1995/04/04 22:29:17 009010 T/JVYW.0001 0 1995/11/07 1:16:50 007858 T/RHOX.0000 0 1995/11/08 23:03:48 002360 T/DQBW.0000 264 1995/11/30 22:56:34 010422 T/FN5W.0001 0 1996/10/21 21:48:52 002575 T/_RxOut 5063 1997/03/09 12:13:07 003130 T/cc158528.i 1 1996/10/13 14:03:55 009028 T/CshLoggedIn 412 1995/12/11 22:33:34 015175 T/3JOZ.0001 264 1996/01/17 18:27:03 003315 T/RIEZ.0001 264 1996/01/24 1:26:54 007815 T/HOOX.0001 264 1996/01/24 6:53:18 007817 T/X5DY.0001 264 1996/01/24 7:29:44 007823 T/RBFY.0001 2 1996/02/07 20:28:14 003222 T/CODE.return_status.338 2 1996/02/07 20:28:27 003224 T/CODE.return_status.374 264 1996/10/30 21:32:14 002574 T/RVT1.0001 264 1997/03/01 17:10:48 011344 T/ZHWKB.0001 5918 1997/03/04 20:03:40 010061 T/Command-00-T05 15217 1997/05/05 19:44:16 014873 T/install.log 528 1997/05/05 19:44:16 014904 T/install.log.info 8161 1997/03/04 19:51:30 010182 T/Command-01-T05 4465 1997/08/12 22:16:18 008603 T/Command-00-T06 1 1997/06/11 22:49:01 003374 T/CshCounter 1425 1998/10/03 13:34:56 009026 T/Command-01-T01 2793 1997/08/12 22:16:19 003413 T/Registerform 1992/09/02 12:33:55 008582 Locale/ 1992/09/02 12:49:47 009136 Locale/Catalogs/ 22276 1992/12/29 21:31:46 009697 Locale/Catalogs/BootX.cd 1992/09/02 12:49:47 009698 Locale/Catalogs/franais/ 1992/09/02 12:46:33 009971 Locale/Catalogs/franais/Sys/ 1540 1992/09/02 11:51:33 009976 Locale/Catalogs/franais/Sys/commodities.catalog 17694 1992/12/29 21:31:52 009977 Locale/Catalogs/franais/Sys/BootX.catalog 2140 1992/09/02 11:51:33 009978 Locale/Catalogs/franais/Sys/libs.catalog 1780 1992/09/02 11:51:33 009979 Locale/Catalogs/franais/Sys/monitors.catalog 9682 1992/09/02 11:51:33 009980 Locale/Catalogs/franais/Sys/utilities.catalog 348 1992/09/02 11:51:33 009981 Locale/Catalogs/franais/Sys/devs.catalog 17392 1992/09/02 11:51:33 009983 Locale/Catalogs/franais/Sys/installer.catalog 3434 1992/09/02 11:51:33 009984 Locale/Catalogs/franais/Sys/system.catalog 3880 1992/09/02 11:51:33 009985 Locale/Catalogs/franais/Sys/dos.catalog 1778 1992/09/02 11:51:33 009986 Locale/Catalogs/franais/Sys/c.catalog 4128 1992/09/02 11:51:33 009987 Locale/Catalogs/franais/Sys/workbench.catalog 3132 1992/09/02 11:51:33 009988 Locale/Catalogs/franais/Sys/prepcard.catalog 2314 1992/09/02 11:51:33 009989 Locale/Catalogs/franais/Sys/amigaguide.catalog 11012 1992/09/02 11:51:33 009990 Locale/Catalogs/franais/Sys/prefs.catalog 1046 1992/12/29 21:31:50 009991 Locale/Catalogs/franais/Sys/reqtools.catalog 1992/09/02 12:37:40 009138 Locale/Countries/ 538 1992/09/02 11:51:33 009700 Locale/Countries/canada_franais.country 538 1992/09/02 11:51:33 009703 Locale/Countries/portugal.country 538 1992/09/02 11:51:33 009706 Locale/Countries/australia.country 538 1992/09/02 11:51:33 009709 Locale/Countries/schweiz.country 538 1992/09/02 11:51:33 009712 Locale/Countries/sverige.country 538 1992/09/02 11:51:33 009715 Locale/Countries/italia.country 538 1992/09/02 11:51:33 009718 Locale/Countries/danmark.country 538 1992/09/02 11:51:33 009721 Locale/Countries/united_states.country 538 1992/09/02 11:51:33 009724 Locale/Countries/norge.country 538 1992/09/02 11:51:33 009727 Locale/Countries/france.country 538 1992/09/02 11:51:33 009730 Locale/Countries/espaa.country 538 1992/09/02 11:51:33 009733 Locale/Countries/belgie.country 538 1992/09/02 11:51:33 009736 Locale/Countries/united_kingdom.country 538 1992/09/02 11:51:33 009739 Locale/Countries/belgique.country 538 1992/09/02 11:51:33 009742 Locale/Countries/deutschland.country 538 1992/09/02 11:51:33 009745 Locale/Countries/sterreich.country 538 1992/09/02 11:51:33 009748 Locale/Countries/canada.country 538 1992/09/02 11:51:33 009751 Locale/Countries/nederland.country 538 1992/09/02 11:51:33 009754 Locale/Countries/suisse.country 538 1992/09/02 11:51:33 009757 Locale/Countries/great_britain.country 538 1992/09/02 11:51:33 009760 Locale/Countries/svizzera.country 1992/09/02 12:37:51 009141 Locale/Help/ 1992/09/02 12:37:52 009763 Locale/Help/franais/ 1992/09/02 12:37:52 009974 Locale/Help/franais/Sys/ 2941 1992/09/02 11:51:33 009992 Locale/Help/franais/Sys/amigaguide.guide 1992/09/02 12:37:43 009143 Locale/Languages/ 1072 1992/09/02 11:51:33 009765 Locale/Languages/franais.language 1997/03/03 23:17:37 008590 Libs/ 10416 1994/01/05 15:17:56 009285 Libs/rexxreqtools.library 27856 1994/02/22 19:19:54 009286 Libs/rexxplslib.library 2876 1992/09/02 13:07:04 009289 Libs/backstab.library 4476 1993/10/07 1:40:18 009290 Libs/OwnDevUnit.library 13288 1994/01/01 14:24:44 009291 Libs/mtool.library 21712 1993/10/07 1:40:26 009292 Libs/xprkermit.library 66336 1993/08/22 23:03:06 009293 Libs/bsh.library 16196 1992/10/04 13:25:06 009294 Libs/dctv.library 28960 1992/09/02 11:51:33 009295 Libs/bullet.library 18072 1993/09/22 12:19:26 009296 Libs/locale.library 4557 1989/05/24 18:37:00 011541 Libs/rexxmathlib.doc 176468 1994/11/11 22:30:00 007166 Libs/post.library 6828 1992/09/02 11:51:33 009297 Libs/iffparse.library 12436 1993/02/07 19:08:56 009298 Libs/arp.library 4280 1992/09/02 11:51:33 009299 Libs/mathtrans.library 40452 1992/09/02 11:51:33 009300 Libs/asl.library 2524 1992/09/02 11:51:33 009301 Libs/rexxsupport.library 24800 1992/09/02 11:51:33 009302 Libs/amigaguide.library 50992 1996/04/08 17:10:36 009303 Libs/reqtools.library 10428 1992/09/02 11:51:33 009304 Libs/mathieeesingtrans.library 15216 1993/02/03 13:45:52 009305 Libs/GDArexxSupport.library 33392 1992/09/02 11:51:33 009306 Libs/rexxsyslib.library 8560 1992/09/02 11:51:33 009307 Libs/commodities.library 5240 1992/09/02 11:51:33 009308 Libs/mathieeedoubbas.library 272 1992/09/02 11:51:33 009309 Libs/version.library 15340 1992/09/02 11:51:33 009311 Libs/diskfont.library 16584 1992/09/02 11:51:33 009312 Libs/mathieeedoubtrans.library 43428 1992/09/02 11:51:33 009313 Libs/68040.library 18436 1994/01/31 23:26:22 009314 Libs/req.library, CED 18388 1992/09/02 11:51:33 009315 Libs/datatypes.library 65840 1992/11/28 14:19:08 009316 Libs/FontEngine.library 10448 1993/11/01 21:38:18 009317 Libs/garbagecollector.library 19004 1993/10/07 1:40:22 009318 Libs/xprbplus.library 1640 1993/04/01 18:23:16 009319 Libs/nofrag.library 61216 1992/12/05 17:16:24 009320 Libs/apig.library 7100 1991/11/12 12:20:06 009321 Libs/conhandler.library 2932 1978/01/13 14:59:52 009322 Libs/diskcode.library 6012 1991/07/09 15:22:31 009323 Libs/libfile.monam 6372 1992/10/12 21:59:52 009324 Libs/midi.library 3580 1978/01/01 0:14:02 009325 Libs/reqtoolsnb.lib 2512 1991/11/12 12:20:22 009326 Libs/tdisk.library 10592 1993/09/14 12:54:59 009327 Libs/translator.library 12608 1980/01/27 8:57:22 009328 Libs/medplayer.library 3160 1993/05/24 15:51:10 009329 Libs/iff.library 10284 1980/01/03 11:22:50 009330 Libs/removelink.library 29556 1994/12/28 17:01:44 001369 Libs/provision.library 7900 1995/03/04 18:02:52 010401 Libs/tower.library 44348 1995/11/07 1:17:01 007958 Libs/thumbnail.library 7076 1989/05/24 18:41:18 011526 Libs/rexxmathlib.library 140696 1996/07/02 16:38:34 008211 Libs/wizard.library 1748 1996/08/10 12:59:56 000243 Libs/hhscybershowkey.library 1196 1996/01/14 14:05:00 000275 Libs/hhsgiokey.library 1036 1996/08/10 13:00:02 000801 Libs/hhsloaderkey.library 2140 1996/08/10 12:59:52 000805 Libs/hhsphotoalbumkey.library 6128 1993/09/28 21:53:48 003117 Libs/powerpacker.library 1997/01/26 21:15:08 011016 Libs/xfd/ 708 1996/06/03 19:04:52 011019 Libs/xfd/FIRE 636 1994/11/05 5:55:34 011022 Libs/xfd/Graftgold_Cruncher 535 1996/06/03 19:04:52 011025 Libs/xfd/.README.FIRST 908 1996/06/03 19:04:54 011028 Libs/xfd/1AM 580 1996/06/03 19:04:52 011031 Libs/xfd/4Vx 492 1996/06/03 19:04:52 011034 Libs/xfd/89A8 2860 1996/06/03 19:04:54 011036 Libs/xfd/=SB= 840 1996/06/03 19:04:54 011043 Libs/xfd/Ace? 552 1996/06/03 19:04:54 011046 Libs/xfd/ALC0 908 1996/06/03 19:04:54 011049 Libs/xfd/AMOS 1196 1996/06/03 19:04:54 011052 Libs/xfd/ArcD 708 1996/06/03 19:04:54 011056 Libs/xfd/ArcR 788 1996/06/03 19:04:54 011059 Libs/xfd/ATOM 888 1996/06/03 19:04:54 011062 Libs/xfd/AXIS 508 1996/06/03 19:04:54 011065 Libs/xfd/BOND 388 1996/06/03 19:04:54 011067 Libs/xfd/CMP1 456 1996/06/03 19:04:54 011069 Libs/xfd/CP 536 1996/06/03 19:04:54 011071 Libs/xfd/CRND 588 1996/06/03 19:04:54 011074 Libs/xfd/CRUN 952 1996/06/03 19:04:54 011077 Libs/xfd/DHp2 936 1996/06/03 19:04:54 011080 Libs/xfd/DPRa 644 1996/06/03 19:04:54 011083 Libs/xfd/Dtpk 544 1996/06/03 19:04:54 011086 Libs/xfd/FUCK 1720 1996/06/03 19:04:54 011089 Libs/xfd/GP 1260 1996/06/03 19:04:52 011094 Libs/xfd/Graftgold 652 1996/06/03 19:04:54 011098 Libs/xfd/HUF 548 1996/06/03 19:04:54 011101 Libs/xfd/HUFF 716 1996/06/03 19:04:52 011104 Libs/xfd/Ice_TSM 772 1996/06/03 19:04:54 011107 Libs/xfd/IFT? 800 1996/06/03 19:04:54 011110 Libs/xfd/JR 640 1996/06/03 19:04:54 011113 Libs/xfd/KDUB 456 1996/06/03 19:04:52 011116 Libs/xfd/LOB 688 1996/06/03 19:04:52 011119 Libs/xfd/LZWH 816 1996/06/03 19:04:54 011122 Libs/xfd/MASM 1256 1996/06/03 19:04:54 011125 Libs/xfd/MASS 892 1996/06/03 19:04:54 011129 Libs/xfd/pack 556 1996/06/03 19:04:54 011132 Libs/xfd/PaK0 484 1996/06/03 19:04:54 011135 Libs/xfd/RLE 988 1996/06/03 19:04:54 011137 Libs/xfd/SPv3 504 1996/06/03 19:04:52 011140 Libs/xfd/SSUR 440 1996/06/03 19:04:52 011142 Libs/xfd/TPWM 608 1996/06/03 19:04:54 011144 Libs/xfd/VDCO 992 1996/06/03 19:04:54 011147 Libs/xfd/Vic2 760 1996/06/03 19:04:54 011150 Libs/xfd/VOL1 1228 1996/06/03 19:04:54 011153 Libs/xfd/XP10 632 1996/06/03 19:04:54 011161 Libs/xfd/XPAC 560 1996/06/03 19:04:52 011164 Libs/xfd/xVdg 27992 1994/08/12 10:31:22 005583 Libs/playsid.library 67444 1996/06/03 19:04:52 011167 Libs/xfdmaster.library 13456 1994/02/20 20:41:30 005642 Libs/xpkmaster.library 1992/09/02 11:54:00 008595 Rexxc/ 300 1992/09/02 11:51:33 009331 Rexxc/TS 364 1992/09/02 11:51:33 009333 Rexxc/TCC 440 1992/09/02 11:51:33 009335 Rexxc/RXC 364 1992/09/02 11:51:33 009337 Rexxc/TCO 208 1992/09/02 11:51:33 009339 Rexxc/WaitForPort 304 1992/09/02 11:51:33 009341 Rexxc/HI 640 1992/09/02 11:51:33 009343 Rexxc/RXSET 968 1992/09/02 11:51:33 009346 Rexxc/RX 740 1992/09/02 11:51:33 009349 Rexxc/RXLIB 300 1992/09/02 11:51:33 009352 Rexxc/TE 1996/12/02 22:33:31 008597 Classes/ 1997/02/10 19:20:23 009354 Classes/DataTypes/ 46036 1992/09/02 11:51:33 009840 Classes/DataTypes/amigaguide.datatype 5888 1992/09/02 11:51:33 009841 Classes/DataTypes/ascii.datatype 3644 1996/03/30 15:18:54 009842 Classes/DataTypes/gif.datatype 3412 1992/09/02 11:51:33 009843 Classes/DataTypes/ilbm.datatype 14512 1992/09/02 11:51:33 009844 Classes/DataTypes/text.datatype 4160 1993/09/28 15:42:10 009845 Classes/DataTypes/pcx.datatype 5936 1992/09/02 11:51:33 009846 Classes/DataTypes/sound.datatype 36724 1993/07/29 20:33:06 009847 Classes/DataTypes/JPEG.datatype 2592 1992/09/02 11:51:33 009848 Classes/DataTypes/8svx.datatype 12488 1992/09/02 11:51:33 009849 Classes/DataTypes/picture.datatype 2716 1993/09/28 15:42:10 009850 Classes/DataTypes/bmp.datatype 2024 1993/09/28 15:42:08 009851 Classes/DataTypes/ico.datatype 2532 1993/09/28 15:42:10 009852 Classes/DataTypes/macpaint.datatype 2832 1995/01/22 13:26:56 003560 Classes/DataTypes/reko.datatype, 68020-version 4672 1995/01/22 19:13:48 003567 Classes/DataTypes/sun.datatype, 68020-version 11192 1995/04/01 16:20:34 009863 Classes/DataTypes/c.datatype 4640 1995/09/30 9:30:32 004688 Classes/DataTypes/SVG.datatype 6512 1995/03/16 21:55:52 002336 Classes/DataTypes/targa.datatype, 68020-version 28424 1995/10/31 18:19:04 015111 Classes/DataTypes/png.datatype 2648 1996/05/20 20:52:52 010057 Classes/DataTypes/zx.datatype 5984 1996/05/27 19:37:12 015331 Classes/DataTypes/font.datatype, V 39.4 4076 1995/03/21 17:21:08 001160 Classes/DataTypes/debox.datatype 79056 1997/02/05 18:35:16 016992 Classes/DataTypes/akPNG.datatype 1992/09/02 11:55:08 009357 Classes/Gadgets/ 5224 1992/09/02 11:51:33 009853 Classes/Gadgets/gradientslider.gadget 12796 1992/09/02 11:51:33 009854 Classes/Gadgets/colorwheel.gadget 1996/12/02 22:33:30 009994 Classes/Codecs/ 1908 1995/03/04 18:02:52 009997 Classes/Codecs/picture.codec 69420 1995/03/04 18:02:52 010002 Classes/Codecs/jpeg.codec 1224 1995/03/04 18:02:50 010397 Classes/codec.class 1996/10/09 20:32:26 008599 Utilities/ 553 1992/09/02 13:32:25 009359 Utilities/Clock.info 1478 1993/05/02 13:27:04 009362 Utilities/Amigaguide.info 837 1992/09/02 13:32:19 009366 Utilities/MultiView.info 11936 1992/09/02 11:51:33 009369 Utilities/More 21180 1992/09/02 11:51:33 009370 Utilities/MultiView 13876 1992/09/02 11:51:33 009371 Utilities/Clock 6656 1993/05/02 13:27:02 009372 Utilities/Amigaguide 113532 1995/04/25 11:47:10 001198 Utilities/Installer 1994/02/21 19:56:22 008601 PSFonts/ 1672 1992/03/14 16:13:54 009373 PSFonts/FunkyFont 1994/02/21 19:56:25 009374 PSFonts/afms/ 4590 1992/03/14 16:13:54 009855 PSFonts/afms/FunkyFont.afm 1997/06/09 21:29:49 008518 _exotic/ 1997/06/09 21:29:42 010221 _exotic/brian/ 2151 1995/06/28 22:14:43 010224 _exotic/brian/bp_str.txt 4108 1995/09/13 20:30:25 010292 _exotic/brian/bp.table 1997/06/09 21:29:43 010302 _exotic/delta/ 14374 1995/06/27 17:39:38 010305 _exotic/delta/dm2.wave 18020 1995/06/27 17:38:34 010477 _exotic/delta/dm2.track 14250 1995/06/27 17:36:36 010514 _exotic/delta/dm2.sound 3552 1995/06/27 17:34:50 010754 _exotic/delta/dm2.keys 4424 1995/06/27 17:32:10 010762 _exotic/delta/dm2.help 11332 1995/06/27 17:31:58 010772 _exotic/delta/dm2.disk 15336 1995/06/27 17:30:04 010856 _exotic/delta/dm2.block 2409 1995/07/05 17:11:51 010887 _exotic/delta/dm1_str.txt 1997/06/09 21:29:44 010893 _exotic/futucomp/ 12980 1995/06/26 18:08:22 010896 _exotic/futucomp/fc14.wav 18216 1995/06/26 18:09:40 010923 _exotic/futucomp/fc14.vol 9088 1995/06/26 18:05:58 010960 _exotic/futucomp/fc14.patt 17302 1995/06/27 11:41:58 010979 _exotic/futucomp/fc14.main 11960 1995/06/26 18:10:14 011305 _exotic/futucomp/fc14.hlp 3048 1995/06/27 13:35:05 011382 _exotic/futucomp/fc14_str.txt 369 1995/06/25 22:30:39 011412 _exotic/futucomp/fc13_voi 2486 1995/06/27 12:21:18 011414 _exotic/futucomp/fc13_str.txt 1997/06/09 21:29:44 011420 _exotic/jamcrack/ 1075 1995/07/19 1:48:55 011423 _exotic/jamcrack/jamcracker_str.txt 18562 1995/07/16 15:02:06 011427 _exotic/jamcrack/jamcracker.main 1997/06/09 21:29:45 011465 _exotic/mark2/ 3636 1995/07/04 20:16:50 011468 _exotic/mark2/m2.set 8360 1995/06/27 14:03:10 011477 _exotic/mark2/m2.sequ 8360 1995/07/04 20:16:08 014924 _exotic/mark2/m2.seq2 6002 1995/06/27 14:02:02 014942 _exotic/mark2/m2.scann 6150 1995/06/26 0:06:32 014955 _exotic/mark2/m2.req 4034 1995/06/26 0:08:32 014969 _exotic/mark2/m2.menu 9762 1995/06/26 0:15:32 014978 _exotic/mark2/m2.inst 9696 1995/06/27 14:00:36 014999 _exotic/mark2/m2.arran 1997/06/09 21:29:45 015019 _exotic/oktaliz/ 23082 1995/06/27 13:47:55 015022 _exotic/oktaliz/oktalyzer_pic 768 1995/06/27 13:26:24 015069 _exotic/oktaliz/oktalizer_str.txt 1997/06/09 21:29:46 015072 _exotic/pumatrack/ 3074 1995/08/14 23:49:36 015075 _exotic/pumatrack/puma_str.txt 10148 1995/08/14 23:43:47 015083 _exotic/pumatrack/puma.wave 14126 2010/10/10 10:43:27 015104 _exotic/pumatrack/puma.main 1997/06/09 21:29:47 015302 _exotic/sid/ 6176 1995/08/19 15:09:47 015305 _exotic/sid/sid2_str.txt 12868 2010/10/10 10:41:50 015319 _exotic/sid/sid2.wave 20586 2010/10/10 10:41:24 015731 _exotic/sid/sid2.patt 18560 2010/10/10 10:40:52 000132 _exotic/sid/sid2.main 18556 2010/10/10 10:40:28 000321 _exotic/sid/sid2.inst 16138 1995/06/28 17:07:18 000359 _exotic/sid/sid.wave 11498 1995/06/28 17:06:26 000392 _exotic/sid/sid.samp 14294 1995/06/28 17:09:00 000416 _exotic/sid/sid.patt 14838 1995/06/28 17:07:58 000445 _exotic/sid/sid.main 1997/06/09 21:29:48 000475 _exotic/synth/ 4678 1995/09/26 23:31:52 000478 _exotic/synth/synth.wave 7472 1995/07/27 23:26:22 000489 _exotic/synth/synth.note 9112 1995/07/26 15:12:38 000505 _exotic/synth/synth.main 7634 1995/07/27 23:25:40 000524 _exotic/synth/synth.instr 4742 1995/07/27 23:24:50 000540 _exotic/synth/synth.diskio 9726 1995/07/27 23:24:00 000551 _exotic/synth/synth.arpeggio 3463 1995/09/13 20:21:06 000571 _exotic/aon_str.txt 5274 1995/09/21 0:10:54 000579 _exotic/pack_song.txt 668 1995/09/29 23:05:05 000591 _exotic/psid.txt 1201 1995/06/30 11:47:13 000594 _exotic/smus_str.txt 2168 1997/01/26 23:28:42 000598 _exotic/thx_str.txt 1997/08/17 21:05:22 008584 Fonts/ 524 1998/05/27 22:54:01 009147 Fonts/Minitel16.font 264 1998/05/27 22:54:01 009150 Fonts/Minitel80.font 1997/08/17 21:04:32 009152 Fonts/_Bullet_Outlines/ 76604 1978/01/08 22:01:23 009155 Fonts/_Bullet_Outlines/Caslon540.type 80162 1978/01/08 22:01:28 009788 Fonts/_Bullet_Outlines/CGOmega.type 89392 1978/01/08 22:01:33 016969 Fonts/_Bullet_Outlines/CSTimes.type 71056 1978/01/08 22:01:38 000764 Fonts/_Bullet_Outlines/CSTriumvirate.type 81866 1978/01/08 22:01:42 000928 Fonts/_Bullet_Outlines/GarthGraphic.type 68546 1978/01/08 22:01:46 001097 Fonts/_Bullet_Outlines/ShannonBook.type 81236 1978/01/08 22:01:51 001764 Fonts/_Bullet_Outlines/Uncial.type 1997/08/17 21:04:42 002157 Fonts/IBM/ 3252 1993/08/26 20:00:42 002160 Fonts/IBM/8 524 1998/05/27 22:53:55 002168 Fonts/DPaint.font 1304 1998/05/27 22:53:56 002171 Fonts/courier.font 1997/08/17 21:04:43 002175 Fonts/siesta/ 2600 1992/04/14 2:28:46 002178 Fonts/siesta/8 1564 1998/05/27 22:53:58 002185 Fonts/helvetica.font 784 1998/05/27 22:53:55 002190 Fonts/ruby.font 264 1998/05/27 22:53:54 002662 Fonts/siesta.font 1997/08/17 21:04:44 002664 Fonts/DPaint/ 640 1993/11/29 21:15:11 002667 Fonts/DPaint/5 3316 1993/11/29 21:15:12 002670 Fonts/DPaint/8 524 1998/05/27 22:53:56 002678 Fonts/diamond.font 1997/08/17 21:04:45 003116 Fonts/ruby/ 4292 1992/09/02 11:51:33 003143 Fonts/ruby/12 5708 1992/09/02 11:51:33 003153 Fonts/ruby/15 3348 1992/09/02 11:51:33 003166 Fonts/ruby/8 1997/08/17 21:04:46 003174 Fonts/_bullet/ 99 1992/09/02 11:51:33 003177 Fonts/_bullet/if.fnt 70726 1992/09/02 11:51:33 003179 Fonts/_bullet/hq3updt.tyq 264324 1992/09/02 11:51:33 003420 Fonts/_bullet/plugin.types, 1990 Agfa Corporation 682 1992/09/02 11:51:33 004137 Fonts/_bullet/hq3.fnt 1972 1992/09/02 11:51:33 004140 Fonts/_bullet/if.uc 1304 1998/05/27 22:53:58 004145 Fonts/times.font 1997/08/17 21:04:53 004149 Fonts/opal/ 3812 1992/09/02 11:51:33 004152 Fonts/opal/12 3284 1992/09/02 11:51:33 004161 Fonts/opal/9 1997/08/17 21:04:53 004169 Fonts/sapphire/ 5040 1992/09/02 11:51:33 004172 Fonts/sapphire/14 6928 1992/09/02 11:51:33 004183 Fonts/sapphire/19 1997/08/17 21:04:54 004198 Fonts/courier/ 3020 1992/09/02 11:51:33 004201 Fonts/courier/11, 1985, 1987 Adobe Systems, Inc. 3444 1992/09/02 11:51:33 004208 Fonts/courier/13, 1985, 1987 Adobe Systems, Inc. 4116 1992/09/02 11:51:33 004216 Fonts/courier/15, 1985, 1987 Adobe Systems, Inc. 5156 1992/09/02 11:51:33 004226 Fonts/courier/18, 1985, 1987 Adobe Systems, Inc. 7556 1992/09/02 11:51:33 004238 Fonts/courier/24, 1985, 1987 Adobe Systems, Inc. 524 1998/05/27 22:53:55 004254 Fonts/opal.font 1997/08/17 21:04:55 004257 Fonts/diamond/ 3884 1992/09/02 11:51:33 004260 Fonts/diamond/12 7188 1992/09/02 11:51:33 004269 Fonts/diamond/20 1997/08/17 21:04:56 004285 Fonts/garnet/ 5380 1992/09/02 11:51:33 004288 Fonts/garnet/16 3732 1992/09/02 11:51:33 004300 Fonts/garnet/9 1997/08/17 21:04:57 004309 Fonts/emerald/ 6168 1992/09/02 11:51:33 004312 Fonts/emerald/17 6988 1992/09/02 11:51:33 004326 Fonts/emerald/20 1997/08/17 21:04:57 004341 Fonts/PlaySID/ 616 1992/09/17 9:13:53 004344 Fonts/PlaySID/8 1997/08/17 21:04:58 004347 Fonts/topaz/ 3192 1992/09/02 11:51:33 004350 Fonts/topaz/11 524 1998/05/27 22:53:57 004358 Fonts/emerald.font 524 1998/05/27 22:53:57 004361 Fonts/garnet.font 264 1998/05/27 22:53:57 004364 Fonts/topaz.font 1998/05/27 22:47:03 004366 Fonts/helvetica/ 3000 1992/09/02 11:51:33 004369 Fonts/helvetica/11, 1985, 1987 Adobe Systems, Inc. 3392 1992/09/02 11:51:33 004376 Fonts/helvetica/13, 1985, 1987 Adobe Systems, Inc. 3936 1992/09/02 11:51:33 004384 Fonts/helvetica/15, 1985, 1987 Adobe Systems, Inc. 5228 1992/09/02 11:51:33 004393 Fonts/helvetica/18, 1985, 1987 Adobe Systems, Inc. 7796 1992/09/02 11:51:33 004405 Fonts/helvetica/24, 1985, 1987 Adobe Systems, Inc. 2288 1994/12/22 15:12:50 004422 Fonts/helvetica/9, 1985, 1987 Adobe Systems, Inc. 1997/08/17 21:05:00 004428 Fonts/times/ 3020 1992/09/02 11:51:33 004431 Fonts/times/11, 1985, 1987 Adobe Systems, Inc. 3548 1992/09/02 11:51:33 004438 Fonts/times/13, 1985, 1987 Adobe Systems, Inc. 4028 1992/09/02 11:51:33 004446 Fonts/times/15, 1985, 1987 Adobe Systems, Inc. 5264 1992/09/02 11:51:33 004455 Fonts/times/18, 1985, 1987 Adobe Systems, Inc. 7700 1992/09/02 11:51:33 004467 Fonts/times/24, 1985, 1987 Adobe Systems, Inc. 524 1998/05/27 22:53:56 004484 Fonts/sapphire.font 264 1998/05/27 22:53:57 004487 Fonts/PlaySID.font 264 1998/05/27 22:53:54 004489 Fonts/IBM.font 185 1978/01/08 22:01:23 004491 Fonts/Caslon540.otag 4 1978/01/08 22:01:23 004493 Fonts/Caslon540.font 194 1978/01/08 22:01:38 004495 Fonts/CSTriumvirate.otag 1997/08/17 21:05:03 004497 Fonts/Condensed60/ 856 1995/08/25 15:47:16 004500 Fonts/Condensed60/6 1908 1995/08/25 15:47:16 004503 Fonts/Condensed60/9 4 1978/01/08 22:01:34 004508 Fonts/CsTimes.font 182 1978/01/08 22:01:33 004510 Fonts/CsTimes.otag 4 1978/01/08 22:01:28 004512 Fonts/CGomega.font 185 1978/01/08 22:01:28 004514 Fonts/CGomega.otag 4 1978/01/08 22:01:38 004516 Fonts/CSTriumvirate.font 195 1978/01/08 22:01:42 004518 Fonts/GarthGraphic.otag 4 1978/01/08 22:01:42 004520 Fonts/GarthGraphic.font 188 1978/01/08 22:01:46 004522 Fonts/ShannonBook.otag 4 1978/01/08 22:01:46 004524 Fonts/ShannonBook.font 182 1978/01/08 22:01:51 004526 Fonts/Uncial.otag 4 1978/01/08 22:01:51 004528 Fonts/Uncial.font 1997/08/17 21:05:06 004530 Fonts/Minitel/ 3784 1993/07/15 20:21:36 004533 Fonts/Minitel/8 3812 1993/07/26 21:48:34 004542 Fonts/Minitel/16 1997/08/17 21:05:07 004551 Fonts/TermSPC80/ 3256 1993/10/07 1:39:54 004554 Fonts/TermSPC80/8 5304 1993/10/07 1:39:52 004562 Fonts/TermSPC80/16 524 1998/05/27 22:53:59 004574 Fonts/TermSPC80.font 1997/08/17 21:05:08 004577 Fonts/TermISO80/ 3256 1993/10/07 1:39:50 004580 Fonts/TermISO80/8 5304 1993/10/07 1:39:48 004588 Fonts/TermISO80/16 524 1998/05/27 22:53:59 004703 Fonts/TermISO80.font 1997/08/17 21:05:09 004706 Fonts/TermISO132/ 2236 1993/10/07 1:39:44 004709 Fonts/TermISO132/8 3388 1993/10/07 1:39:42 004715 Fonts/TermISO132/16 524 1998/05/27 22:54:00 004723 Fonts/TermISO132.font 1997/08/17 21:05:10 004726 Fonts/TermIBM80/ 3256 1993/10/07 1:40:14 004729 Fonts/TermIBM80/8 5304 1993/10/07 1:40:12 004737 Fonts/TermIBM80/16 524 1998/05/27 22:54:00 004749 Fonts/TermIBM80.font 1997/08/17 21:05:11 004752 Fonts/TermDDC80/ 3256 1993/10/07 1:40:10 004755 Fonts/TermDDC80/8 5304 1993/10/07 1:40:08 004763 Fonts/TermDDC80/16 524 1998/05/27 22:54:00 004967 Fonts/TermDDC80.font 1997/08/17 21:05:12 004970 Fonts/TermDDC132/ 2488 1993/10/07 1:40:06 004973 Fonts/TermDDC132/8 3768 1993/10/07 1:40:04 004979 Fonts/TermDDC132/16 524 1998/05/27 22:54:00 005161 Fonts/TermDDC132.font 1997/08/17 21:05:13 005164 Fonts/Minitel16/ 3388 1993/07/26 21:30:14 005167 Fonts/Minitel16/8 5244 1993/07/26 21:32:26 005175 Fonts/Minitel16/16 1997/08/17 21:05:14 005187 Fonts/Minitel80/ 2376 1993/07/12 21:35:56 005190 Fonts/Minitel80/8 524 1998/05/27 22:53:59 005196 Fonts/Minitel.font 1997/08/17 21:05:15 005199 Fonts/A64/ 732 1993/10/19 12:19:05 005202 Fonts/A64/6 264 1998/05/27 22:54:01 005205 Fonts/A64.font 524 1998/05/27 22:53:58 005207 Fonts/Condensed60.font 1304 1998/05/27 22:54:02 005210 Fonts/DGSansSerif.font 1997/08/17 21:05:16 005214 Fonts/DGSansSerif/ 3352 1995/08/25 15:47:16 005217 Fonts/DGSansSerif/11 3600 1995/08/25 15:47:16 005225 Fonts/DGSansSerif/13 2644 1995/08/25 15:47:16 005234 Fonts/DGSansSerif/7 2852 1995/08/25 15:47:16 005241 Fonts/DGSansSerif/8 3032 1995/08/25 15:47:16 005248 Fonts/DGSansSerif/9 264 1998/05/27 22:54:02 005255 Fonts/newtopaz.font 1997/08/17 21:05:17 005257 Fonts/newtopaz/ 3332 1995/08/25 15:47:16 005260 Fonts/newtopaz/8 264 1998/05/27 22:54:02 005268 Fonts/GoldED.font 1997/08/17 21:05:18 005270 Fonts/GoldED/ 3132 1993/12/19 23:10:30 005273 Fonts/GoldED/10 1997/08/17 21:05:18 005281 Fonts/musicline/ 2004 1995/09/13 21:49:04 005284 Fonts/musicline/8 2960 1995/09/13 19:30:22 005289 Fonts/musicline/7 524 1998/05/27 22:54:02 005296 Fonts/Musicline.font 1997/08/17 21:05:19 005299 Fonts/DCTV-Viewer/ 3176 1995/04/02 2:11:20 005302 Fonts/DCTV-Viewer/8e 264 1998/05/27 22:54:02 005310 Fonts/DCTV-Viewer.font 1997/08/17 21:05:20 005312 Fonts/Personal/ 3900 1995/06/19 18:56:06 005315 Fonts/Personal/8 264 1998/05/27 22:54:02 005324 Fonts/Personal.font 1997/08/17 21:05:21 005326 Fonts/KaraGRANITE/ 37096 1989/01/10 21:05:21 005329 Fonts/KaraGRANITE/55.8C 264 1998/05/27 22:54:03 005404 Fonts/KaraGRANITE.font 264 1998/05/27 22:54:03 005406 Fonts/microknight.font 1997/08/17 21:05:22 005408 Fonts/microknight/ 2888 1997/03/19 19:21:37 005411 Fonts/microknight/8 1998/04/29 17:56:30 010555 Fonts/Chorus/ 2616 1995/07/27 12:57:10 010558 Fonts/Chorus/8 264 1998/05/27 22:54:03 010565 Fonts/Chorus.font 1995/07/17 23:41:34 008607 ARexx/ 1994/06/13 17:49:19 009410 ARexx/Rexx/ 724 1994/03/30 18:56:18 009866 ARexx/Rexx/NextError.ced 371 1994/03/30 18:55:14 009869 ARexx/Rexx/Make.ced 414 1994/03/30 18:55:10 009871 ARexx/Rexx/Compile.ced 414 1994/03/30 18:55:10 009412 ARexx/Compile.ced 371 1994/03/30 18:55:14 009414 ARexx/Make.ced 724 1994/03/30 18:56:18 009416 ARexx/NextError.ced 3305 1992/08/01 10:56:48 009042 ARexx/AddToLabelDataBase.pprx 816 1992/03/14 19:12:38 009043 ARexx/ADProComm.rexx 2259 1992/03/14 19:12:46 009046 ARexx/ADProHotLink.pprx 3619 1992/03/14 19:12:48 008975 ARexx/Align.pprx 1021 1992/03/14 19:12:52 008976 ARexx/AllCaps.pprx 6052 1992/03/14 19:12:50 009047 ARexx/AlterBoxesOnPages.pprx 2798 1993/02/19 14:08:02 009048 ARexx/AutoImport.pprx 1075 1993/01/24 13:45:18 008981 ARexx/AutoSave.pprx 759 1992/03/14 19:12:58 008927 ARexx/AutoSave.pprx.info 26810 1993/01/29 18:31:34 009049 ARexx/BordersSimpleShapes.pprx 4711 1992/03/14 19:12:46 009050 ARexx/BoxAttr.pprx 944 1992/03/14 19:12:38 009051 ARexx/BoxColors.pprx 3650 1993/01/29 18:31:00 009054 ARexx/BoxesFrontToBack.pprx 2277 1992/08/02 18:26:00 009055 ARexx/BoxResize.pprx 946 1992/03/14 19:12:40 009056 ARexx/Calculator.pprx 821 1992/03/14 19:12:42 009059 ARexx/CommandLine.pprx 2355 1992/03/14 19:12:58 009062 ARexx/CopyBoxAttributes.pprx 4234 1993/02/15 15:56:24 009063 ARexx/CopyBoxContents.pprx 2101 1992/03/14 19:12:44 009064 ARexx/CopyBoxToPages.pprx 1065 1992/03/14 19:12:42 009065 ARexx/CopyPages.pprx 2144 1992/03/14 19:12:44 009066 ARexx/CopyPageSpecs.pprx 1028 1992/03/14 19:12:46 009067 ARexx/DeleteRange.pprx 3666 1992/03/14 19:12:40 009068 ARexx/DropCaps.pprx 2081 1992/03/14 19:12:54 009069 ARexx/DropShadowBox.pprx 1413 1992/03/14 19:12:40 009070 ARexx/DropShadowHeader.pprx 4719 1992/03/14 19:13:00 009071 ARexx/EnterPersonalInfo.pprx 1900 1993/02/10 13:02:32 009072 ARexx/FindAndReplace.pprx 1127 1992/07/17 23:28:18 009073 ARexx/FitBitmapToBox.pprx 2424 1993/02/15 15:58:38 009074 ARexx/GetTaggedText.pprx 898 1992/03/14 19:12:48 009075 ARexx/GreekBoxes.pprx 4623 1992/03/14 19:12:52 009078 ARexx/GroupAttr.pprx 2080 1992/03/14 19:12:56 009079 ARexx/GroupCopyBoxAttr.pprx 4072 1993/02/15 15:59:40 009080 ARexx/GroupCopyBoxContents.pprx 1820 1993/02/15 16:00:26 009081 ARexx/GroupCopyToPages.pprx 4513 1992/03/14 19:12:44 009082 ARexx/GroupDistribute.pprx 2027 1992/03/14 19:12:44 009083 ARexx/GroupMove.pprx 1957 1992/03/14 19:12:56 009084 ARexx/GroupRotate.pprx 2493 1992/03/14 19:12:56 009085 ARexx/GroupScale.pprx 3122 1992/03/14 19:12:56 009086 ARexx/GroupSpace.pprx 3548 1992/03/14 19:12:48 009087 ARexx/GroupTile.pprx 1018 1992/03/14 19:12:40 009088 ARexx/InitialCaps.pprx 3789 1993/02/19 14:11:00 009091 ARexx/Insertdoc.pprx 2366 1992/03/14 19:12:46 009092 ARexx/InsertPersonalInfo.pprx 1118 1992/07/17 23:28:08 009093 ARexx/LandscapePage.pprx 7312 1993/02/15 16:02:26 009094 ARexx/MailMerge.pprx 3770 1992/07/18 23:28:04 009095 ARexx/MakeBarChart_Horz.pprx 3698 1992/07/18 23:28:02 009096 ARexx/MakeBarChart_Vert.pprx 2727 1992/03/14 19:12:46 009097 ARexx/MakeBoxIntoColumns.pprx 2376 1992/03/14 19:12:40 009098 ARexx/MakeGuides.pprx 4914 1992/07/17 23:27:58 009099 ARexx/MakePieChart.pprx 1167 1992/03/14 19:12:38 009100 ARexx/MovePage.pprx 1131 1992/03/14 19:12:38 009101 ARexx/NoCaps.pprx 5688 1993/02/19 14:11:52 009102 ARexx/ProCalcTableImport.pprx 2425 1993/02/19 14:13:46 009103 ARexx/ProCalcTableUpdate.pprx 2458 1993/02/15 16:05:50 009104 ARexx/ReplaceMergeCodes.pprx 7102 1993/02/01 18:09:28 009105 ARexx/SavePrefs.pprx 2396 1992/03/14 19:12:38 009106 ARexx/SetPageSize.pprx 1570 1992/03/14 19:12:38 009107 ARexx/SmallCaps.pprx 2402 1992/03/14 19:13:02 009108 ARexx/StepAndRepeat.pprx 2066 1993/01/28 18:07:44 009109 ARexx/SubstituteFont.pprx 3330 1993/01/28 18:04:46 009110 ARexx/TableImport.pprx 886 1992/03/14 19:12:44 009111 ARexx/UnGreekBoxes.pprx 7308 1993/02/19 14:01:40 009114 ARexx/UnitsConverter.pprx 1047 1992/03/14 19:12:38 008982 ARexx/counter.rexx 559 1992/07/18 13:11:32 008983 ARexx/FontList.rexx 3110 1992/03/14 19:12:38 008986 ARexx/FormatDate.rexx 658 1992/03/14 19:12:48 008987 ARexx/getdirlist.rexx 266 1992/03/14 19:12:44 008990 ARexx/ItemToFront.rexx 2635 1992/02/29 15:45:32 008971 ARexx/launch.rexx 2424 1993/02/15 13:14:12 008993 ARexx/PPageAutoSave.rexx 622 1993/02/15 15:39:24 008995 ARexx/PPSetup.rexx 363 1993/01/29 18:30:20 008998 ARexx/SafeEndEdit.rexx 375 1993/01/28 16:20:34 009000 ARexx/SafeSetEdit.rexx 1997/06/09 21:22:12 010066 _structure/ 333 1995/06/26 12:32:28 010464 _structure/arc_str 424 1995/06/22 13:38:59 010825 _structure/tar_str.txt 667 1995/06/26 13:31:26 010827 _structure/lha.txt 1799 1995/06/22 11:59:23 010830 _structure/zip_str.txt 1968 1995/06/22 15:26:06 010835 _structure/zoo_str.txt 1007 1996/03/19 20:56:40 010427 _structure/lzx_str.txt 2180 1996/04/05 1:01:24 002965 _structure/warp_str.txt 6911 1995/10/02 22:59:07 003887 _structure/exotic.txt 18395 1996/11/24 11:26:45 010081 _structure/inst.txt 1996/10/10 19:01:31 010694 SquirrelSCSI/ 1996/10/09 20:33:30 010700 SquirrelSCSI/SCSIMounter/ 503 1995/01/26 11:29:18 010703 SquirrelSCSI/SCSIMounter/SCSIMounter.guide.info 19234 1994/12/05 17:01:02 010705 SquirrelSCSI/SCSIMounter/SCSIMounter.guide 868 1995/01/26 11:29:18 010812 SquirrelSCSI/SCSIMounter/SCSIMounter.doc.info 18167 1994/12/05 16:56:06 010815 SquirrelSCSI/SCSIMounter/SCSIMounter.doc 1044 1995/01/26 11:29:19 015927 SquirrelSCSI/SCSIMounter/SCSIMounter.info 32356 1994/12/05 16:05:46 015931 SquirrelSCSI/SCSIMounter/SCSIMounter 628 1995/01/26 11:29:26 015362 SquirrelSCSI/SCSIMounter.info 1996/10/09 20:32:16 015365 SquirrelSCSI/Extras/ 1996/10/09 20:32:17 015368 SquirrelSCSI/Extras/DOSDrivers/ 523 1995/05/25 10:06:56 015371 SquirrelSCSI/Extras/DOSDrivers/PC270C.info 666 1995/01/26 10:26:54 015374 SquirrelSCSI/Extras/DOSDrivers/PC270C 523 1995/05/25 10:06:56 015377 SquirrelSCSI/Extras/DOSDrivers/FP0.info 504 1995/01/26 10:22:32 015380 SquirrelSCSI/Extras/DOSDrivers/FP0 632 1995/01/23 16:31:48 015382 SquirrelSCSI/Extras/DOSDrivers.info 628 1995/01/26 11:29:26 015385 SquirrelSCSI/Extras.info 5409 1995/08/29 14:18:54 015996 SquirrelSCSI/ReadMe 556 1995/06/02 18:32:38 016008 SquirrelSCSI/ReadMe.info 9886 1996/10/09 0:13:09 000088 SquirrelSCSI/ZIPMount_12.lha 4650 1996/10/09 0:13:14 000162 SquirrelSCSI/ZipTool12.lha 24104 1996/10/09 0:12:47 000283 SquirrelSCSI/SCSIdevs.lha 27553 1996/10/09 10:02:46 000173 SquirrelSCSI/ProbeSCSI008.lha 11834 1996/04/25 12:02:50 000020 SquirrelSCSI/ZIPMount.guide 628 1996/10/10 21:32:53 010697 SquirrelSCSI.info 1997/05/01 12:30:58 001207 _str/ 7981 1995/09/18 22:24:59 001210 _str/fred_str.txt 2470 1995/06/29 15:42:22 001227 _str/m2_str.txt 1987 1996/05/21 0:25:53 001233 _str/tfmx.doc 20554 1996/05/15 7:55:36 001238 _str/tfmx.patt 82036 1996/05/14 0:10:40 001280 _str/tfmx.pic1 20554 1996/05/15 7:41:53 001983 _str/tfmx.pic6 20554 1996/05/15 7:49:54 002026 _str/tfmx.track 14715 1996/04/09 2:16:07 002618 _str/tfmx.txt 2360 1996/05/20 23:46:04 002648 _str/tfmx_str.txt 852 1996/05/21 0:33:05 002654 _str/tfmx_str2.txt 9133 1995/11/07 22:28:47 002657 _str/ult_form.txt2 56917 1995/07/27 17:59:24 002834 _str/digi.txt 44640 1995/07/27 22:36:48 003012 _str/digi2.txt.gz 48594 1995/06/28 18:48:08 001366 _str/TME_STR.TXT 64186 1997/01/11 18:14:24 001525 _str/MLED.TXT.gz 10480 1997/11/03 21:49:07 008540 MON.paradox, ExoticRipper 2.22 68020+ CeBIT'94 by Turbo & Marley/Infect. 51324 1997/11/03 22:10:30 002278 mod.brian_the_lion, - [01:09] - (PHA) Ripped & Converted with Pro-Wizard v2.16 by Gryzor 9382 1998/02/11 22:53:53 010054 MOD.matkamies, ExoticRipper 2.22 68020+ CeBIT'94 by Turbo & Marley/Infect. 9338 1998/02/11 23:08:14 010535 FRED.stardust_intro, ExoticRipper 2.22 68020+ CeBIT'94 by Turbo & Marley/Infect. 628 1996/10/10 21:32:53 000011 Storage.info unadf-0.7.11a/Docs/0000755000000000000000000000000010534613270012425 5ustar rootrootunadf-0.7.11a/Docs/API.txt0000644000000000000000000001612510534557264013616 0ustar rootrootThe ADFlib API quick overview ***************************** outdated ! But may be useful anyway... Always read ADFlib structures, never change a value directly, the behaviour of the library could then become unforeseeable. Minimal C program with ADFlib ----------------------------- #include /* for puts() */ #include"adflib.h" ENV_DECLARATION; int main(int argc, char *argv[]) { adfEnvInitDefault(); puts("hello world"); adfEnvCleanUp(); } Device ------ struct Device { int devType; /* see adf_str.h */ BOOL readOnly; long size; /* in bytes */ int nVol; /* partitions */ struct Volume** volList; long cylinders; /* geometry */ long heads; long sectors; BOOL isNativeDev; void *nativeDev; }; struct Device* adfMountDev(char* name) mounts and allocates a device (real or dump) void adfDeviceInfo(struct Device* dev) prints device info to stdout : must be rewritten for another GUI void adfUnMountDev(struct Device* dev) void adfCreateHd(struct Device* dev, int nbPartitions, struct Partition** part) create a filesystem for harddisk with one or several partition (see hd_test2.c) void adfCreateFlop(struct Device* dev, char* name, int flags) flags are for ffs, dircache or international (see fl_test.c) Volume ------ struct Volume { struct Device* dev; SECTNUM firstBlock; /* first block of data area (from beginning of device) */ SECTNUM lastBlock; /* last block of data area (from beginning of device) */ SECTNUM rootBlock; /* root block (from firstBlock) */ char dosType; /* FFS/OFS, DIRCACHE, INTERNATIONAL */ BOOL bootCode; int datablockSize; /* 488 or 512 */ char *volName; long bitmapSize; /* in blocks */ SECTNUM *bitmapBlocks; /* bitmap blocks pointers */ struct bBitmapBlock **bitmapTable; BOOL *bitmapBlocksChg; SECTNUM curDirPtr; }; struct Volume* adfMount(struct Device* dev, int partition, BOOL readOnly) The first partition is #0 To be called after adfCreateFlop(), adfCreateHd() or adfMountDev(). void adfVolumeInfo(vol) Display volume info to stdout, must be rewritten for another GUI void adfUnMount(struct Volume *vol) Dump device (.ADF) ------------------ struct adfCreateDumpDevice(char*, int cyl, int heads, int sectors) To be used in place of adfMountDev(). Create a filename of the right size, nothing else File ---- struct File* adfOpenFile(struct Volume *volume, char* filename, char* mode) mode = "r" or "w" void adfCloseFile(struct File* file) long adfReadFile(struct File* file, long length, unsigned char* buffer) returns the number of bytes read long adfWriteFile(struct File* file, long length, unsigned char* buffer) returns the number of bytes written BOOL adfEndOfFile(struct File* file) Directory --------- struct List* adfGetDirEnt(struct Volume* vol, SECTNUM nSect) Returns a linked list with the directory entries. Each cell content of the list must be freed with adfFreeEntry() void adfFreeEntry(struct Entry *entry) SECTNUM adfChangeDir(struct Volume* vol, char* dirname) change current directory void adfParentDir(struct Volume* vol) change current directory void printEntry(struct Entry* entry) print the cell content to stdout void CreateDir(struct Volume* vol, SECTNUM parentSect, char* name) Callbacks mechanism ------------------- * The library environment : 'struct Env adfEnv' This variable is the only global variable of the library. It contains callbacks for error and notification messages, and global variables. By default, adfEnvInitDefault() initialize adfEnv functions that display messages to stderr. You must use adfSetEnv() to use your own defined functions. The environment must be clean up with adfEnvCleanUp(). Four functions are available : - (*adfEnv.eFct)(char*), called by ADFlib for a fatal error. It STOPS the library : you must redefine yourself a more friendly to handle this kind of error. - (adfEnv.wFct)(char*), called for warnings. It is called when something wrong happens, but processing can continue. - (adfEnv.vFct)(char*), called to display verbose messages. - (*adfEnv.notifyEnv)(SECTNUM p, int t), called to tell that the volume structure has changed. The value p give where the change appeared, t the type of the value (ST_DIR,ST_FILE,...). The environment also contains access to nativeFunctions. * Native device and functions By default, the library is compiled to manage .ADF files (dump files) and real devices like harddisk and removable disks (called native devives) on ONE defined plateform (WinNT/Intel or Linux/68k...) To add a new plateform to be supported by ADFlib, you must write your own files adf_nativ.h and adf_nativ.c. . data types adf_nativ.h defines two structures : - 'struct nativeDev'. It contains all the variable necessary for the native device management. You can add here whatever you what to be able to manage your real device on your plateform ! - 'struct nativeFunctions'. It defines the minimal API between ADFlib and the specific native part. The functions names and prototypes must not be changed, since they are called by the library. It is possible to add other functions. The type device 'struct Device' contains one variable 'void* nativeDev'. It is allocated within adf_nativ.c by adfInitDevice(). Another variable 'BOOL isNativeDev' tells if the ADFlib is working with a dump file (.ADF) or a real device. 'adfEnv' contains one variable 'void *nativeFct'. adfEnvInitDefault() allocates it by calling the function adfInitNativeFct(). . callback functions : The structure 'struct nativeFunctions' must have at least : BOOL (*adfInitDevice)(struct Device*, char*) BOOL (*adfNativeReadSector)(struct Device*, long, int, unsigned char*) BOOL (*adfNativeWriteSector)(struct Device*, long, int, unsigned char*) BOOL (*adfIsDevNative)(char*) void (*adfReleaseDevice)() For example, adfMountDev() calls adfInitDevice() this way : struct nativeFunctions *nFct; ... /* struct Device* dev allocation */ nFct = adfEnv.nativeFct; /* was of type void* */ /* only once ! */ dev->isNativeDev = (*nFct->adfIsDevNative)(filename); /* choose between dump or a real device */ if (dev->isNativeDev) (*nFct->adfInitDevice)(dev, filename); else adfInitDumpDevice(dev, filename); You must define one function to initialize a device, for example : BOOL myInitDevice(struct Device *dev, char* name) { /* allocate and initailize dev->nativeDev */ /* return TRUE if everything happens right */ } or BOOL myIsDevNative(char* name) { /* for a Unix like platform */ return( strncmp("/dev/",name,5)==0 ); } And so on to read, write a 512 bytes block, and release the native device. The function 'adfInitNativeFct()', also defined in adf_nativ.c (and .h), makes the names and the ADFlib native API : void adfInitNativeFct() { struct nativeFunctions *nFct; nFct = (struct nativeFunctions*)adfEnv.nativeFct; nFct->adfInitDevice = myInitDevice ; nFct->adfNativeReadSector = myReadSector ; ... } But the prototypes must stay the same ! unadf-0.7.11a/Docs/version0.7.9d_gary.txt0000644000000000000000000000543710534557264016460 0ustar rootroot ADFLib changes - Wednesday 16/10/02 ----------------------------------- Background ---------- Bjark Viksoe changed ADFLib 0.7.9b in or before December 2001. Experimental version sent to me by Laurent in December 2001, soon to be released as 0.7.9c. Changes tried with ADFOpus then put aside due to difficulties compiling. Successfully tried again in October 2002, having neither heard anything more from Laurent nor seen a later version at the web site. Bjark Viksoe's changes removed the dynamic projects and changed a number of parameters such as where compiled files were stored. These were potentially not portable and operated outside the compilation directory e.g. "..\..\AdfLib...", "C:\Temp". Laurent's original settings were slightly at odds with common VC++ practice i.e. Win32 and Debug directories used for compiled files rather than Release and Debug; Debug executables used Release libs rather than debug versions. Enter Gary with a shiny version of ADF Opus to release and a desire to release it with a clean and equally shiny ADFLib 0.7.9c distribution. Method ------ I started with a clean installation of ADFLib 0.7.9b. Loading this into VC++ 6 SP5 updated the project and workspace files to VC++ 6 versions. Next, I unpacked a clean installation of the potential 0.7.9c version received from Laurent. I then used WinDiff to determine exactly what changes Bjark had made and manually edited the 0.7.9b files to match. Changes ------- -Reinstated dynlib, dynunadf and staticunadf by starting with V0.7.9b. -Returned to original ADFLib compilation settings as above, then made some subtle changes. -Release output files now go to Bin/Win32/Release, rather than Bin/Win32, for symmetry and standardisation. Intermediate files still go to Release and Debug. -Debug dynunadf and staticunadf now use the debug libs, not the release ones, to allow full debugger access. -Fixed a path setting problem which caused a failure to find adflibd.lib. -Changed Bjark's setting of "C7 Compatible" back to "Program Database for Edit and Continue" for consistency with the other projects. -Annotated Bjark's changes with /* BV */ for easy identification. -Removed C++ comment tags and replaced them with C tags across the board. ADFLib should hopefully be pure C again now. -Removed a change implemented for Opus which was inadvertantly left in during earlier updates i.e. a string added to struct nativeDevice in adf_nativ.h. -Updated Laurent's copyright on every page to include 2002. -Updated the version and date strings to: #define ADFLIB_VERSION "0.7.9c" #define ADFLIB_DATE "16 October, 2002" -Everything compiles cleanly with no warnings. :-) -Bjark's changes appear to support non-standard FD ADFs up to 83 tracks. Can we confirm this? unadf-0.7.11a/Docs/api_device.html0000644000000000000000000001646010534557264015424 0ustar rootroot Device

the Device API


Use cases

  • Mounting volume of a existing device (ADF dump or real one) :
    1. adfMountDev()
    2. adfMount()
    3. adfUnMount()
    4. adfUnMountDev()

  • Creating an ADF dump of a floppy :
    1. adfCreateDumpDevice()
    2. adfCreateFlop()
    3. adfMount()
    4. adfUnMount()
    5. adfUnMountDev()

  • Creating an ADF dump of a harddisk :
    1. adfCreateDumpDevice()
    2. adfCreateHd()
    3. adfMount()
    4. adfUnMount()
    5. adfUnMountDev()

  • Creating an new filesystem for an harddisk on a real device :
    1. adfMountDev()
    2. adfCreateHd()
    3. adfMount()
    4. adfUnMount()
    5. adfUnMountDev()

Data structures

Warning ! None of the fields of the structure below must be modified directly. In this case, i can not tell how will behave the library. Unless specified, read access is of course allowed.

The dynamic memory allocation/releasing is done by the library (i hope :).

struct Device {
    int devType;                      /* DEVTYPE_FLOPDD, DEVTYPE_FLOPHD or DEVTYPE_HARDDISK */
    long size;                        /* size in bytes of the media. ADFlib is limited to 4Gb */
    
    int nVol;                         /* number of partitions (volumes) */
    struct Volume* *volList;          /* volumes */

    long cylinders, heads, sectors;   /* device geometry */
    
    BOOL isNativeDev;

    void *nativeDev;                  /* native specific and private structure */
}

The Partition structure is used with adfCreateHd().

struct Partition{
    long startCyl;      /* starting cylinder of the usable space : should be 2 */
    long lenCyl;        /* length of this area, in cylinders */

    char* volName;      /* name of the volume, if any. Instead filled with 0.  */

    int volType;        /* filesystem caracteristics : use the flags FSMASK_FFS, 
                            FSMASK_INTL and FSMASK_DIRCACHE                     */

} 

adfMountDev()

Syntax

struct Device* adfMountDev( char* name)

Description

Mounts a device. The name could be a filename for an ADF dump, or a real device name like "|F:" for the Win32 F: partition.
The real device name is plateform dependent.

Return values

NULL if an error occurs, a Device structure pointer instead.

Internals

  1. Allocation of struct Device *dev
  2. Calls adfIsNativeDev() to determine if the name point out a ADF dump or a real (native) device. The field dev->isNativeDev is filled.
  3. Initialize the (real or dump) device. The field dev->size is filled.
  4. dev->devType is filled.
  5. The device is mounted : dev->nVol, dev->volList[], dev->cylinders, dev->heads, dev->sectors are filled.
  6. dev is returned
Warning, in each dev->volList[i] volumes (vol), only vol->volName (might be NULL), vol->firstBlock, vol->lastBlock and vol->rootBlock are filled !

See also

struct Device, real (native) devices

Files

Real devices allocation : adf_nativ.c, adf_nativ.h
ADF allocation : adf_dump.c, adf_dump.h


adfUnMountDev()

Syntax

void adfUnMountDev( struct Device* dev)

Description

Releases a Device and frees related resources.

Internals

  1. Frees dev->volList[]
  2. Releases the ADF dump or real (native) device : call the suited function.

adfCreateHd()

Syntax

RETCODE adfCreateHd(struct Device* dev, int nPart, struct Partition* *partList )

Description

Create the filesystem of a device which will be used as an Harddisk. AdfMount() must be used after to mount a volume (partition).

In case of a new ADF dump, adfCreateDumpDevice() must be called before to create an empty media of the right size.

An Harddisk ADF dump created with ADFlib -can not be- used back by the AmigaDOS, since some fields of the header structures are missing : they can not be automatically determined.

Return values

RC_OK, or Something different in case of error.

Examples

Creation of an ADF Zip disk dump :
struct Partition part1;
struct Partition **partList;
struct Device *hd;
RETCODE rc;

/* Env init */

/* cyl = 2891, heads = 1, sectors = 68 */
hd = adfCreateDumpDevice("newdev",2891,1,68);
if (!hd) { /* cleanup and exit */ }

/* allocation of partlist[] */

/* the filesystem definition : size, FFS with DIRCACHE */
part1.startCyl = 2;
part1.lenCyl = 2889;
part1.volName = strdup("zip");
part1.volType = FSMASK_FFS|FSMASK_DIRCACHE;

partList[0] = &part1;

/* creates the filesystem */
rc = adfCreateHd(hd,1,partList);
if (rc!=RC_OK) { /* something wrong, cleaning up and exit */ }

/* freeing of partList[] and part1.volName */

/* device usage */

adfUnMountDev(hd);

/* Env cleanup */

Internals

  1. Creates and fill dev->volList[]
  2. Creates the Harddisk header structures on the media. It uses usually the 2 first cylinders of the device.

adfCreateFlop()

Syntax

RETCODE adfCreateFlop(struct Device* dev, char* volName, int volType )

Description

Creates the filesystem of a DD or HD floppy. AdfMount() must be used after to mount the only volume.

In case of a new ADF dump, adfCreateDumpDevice() must be called before to create an empty media of the right size.

An Harddisk ADF dump created with ADFlib -can be- used back by the AmigaDOS.

Return values

RC_OK, or Something different in case of error.

Examples

struct Device *flop;

/* Env init */

/* creates a DD floppy empty dump */
/* cyl = 80, heads = 2, sectors = 11. HD floppies has 22 sectors */
flop = adfCreateDumpDevice("newdev", 80, 2, 11);
if (!flop) { /* cleanup and exit */ }

/* create the filesystem : OFS with DIRCACHE */
rc = adfCreateFlop( flop, "empty", FSMASK_DIRCACHE );
if (rc!=RC_OK) { /* error : cleanup and exit() */

/* device usage */

adfUnMountDev(flop);

/* Env cleanup */

Internals

  1. Allocation of dev->volList[]. It contains one volume.
  2. Creation of the volume

ADF only : adfCreateDumpDevice()

Syntax

struct Device* adfCreateDumpDevice(char* filename, long cyl, long heads, long sect)

Description

Create a file of the right size, and fills some fields of the Device structure. Must be followed by adfCreateFlop() and adfCreateHd().

Return values

the Device, NULL in case of error.

Examples

See adfCreateFlop() and adfCreateHd() examples.

Internals

  1. Allocate struct Device* dev
  2. Allocate dev->nativeDev
  3. Create an empty file with a size equals to : cyl*heads*sect*512.
  4. Open this file with "rb+" mode
  5. Fills dev->cylinders, dev->heads, dev->sectors, dev->size, dev->devType, and dev->nVol = 0.
  6. Returns dev
unadf-0.7.11a/Docs/api_salv.html0000644000000000000000000000451410534557264015127 0ustar rootroot Salvage

the Salvage API


Typical usage

#include"adflib.h"


int main()
{
    struct List *list, *cell;

    /* initialization */    
    /* the device and volume are mounted */

    cell = list = adfGetDelEnt(vol);
    while(cell) {
        block =(struct Block*) cell->content;
        printf("%s %d %d %ld\n",block->name,block->type,block->secType,
            block->sect);
        cell = cell->next;
    }
    /* we noted the entry 883 and 885 */
    adfFreeDelList(list);

    /* 883 is a file */
    if (adfCheckEntry(vol,883,0)==RC_OK)
        adfUndelEntry(vol,vol->curDirPtr,883); 

    /* 885 is a directory */
    if (adfCheckEntry(vol,885,0)==RC_OK)
        adfUndelEntry(vol,vol->curDirPtr,885);
 
    /* unmounts done */
    /* cleanup */
}

adfGetDelEnt()

Syntax

struct List* adfGetDelEnt(struct Volume *vol)

Description

Returns the list of the files/directories that MIGHT be undeleted. The entries must be checked before !

See adfFreeDelList() to free this list.
See adfCheckEntry() to check if the entry could be undeleted.

Internals

Scans all the blocks of the volume to find directory blocks and file header blocks that are not allocated in the bitmap.


adfCheckEntry()

Syntax

RETCODE adfCheckEntry(struct Volume* vol, SECTNUM nSect, int level)

Description

Checks if an entry (directory or file) could be undeleted.

The 'level' argument is not used yet. Could be set to 0.


adfUndelEntry()

Syntax

RETCODE adfUndelEntry(struct Volume* vol, SECTNUM parent, SECTNUM nSect)

Description

Undelete a directory or a file. The parent directory of an entry must exist.

Internals

Add the entry first block pointer in the parent directory list and allocated the related blocks in the bitmap.

void adfFreeDelList(struct List* list)

Syntax

void adfFreeDelList(struct List* list)

Description

Free the list of deleted entries.

unadf-0.7.11a/Docs/api_volume.html0000644000000000000000000001035710534557264015473 0ustar rootroot Volume

the Volume API


Use cases

See Device API use cases.


Data structures

struct Volume{
    struct Device *dev;            /* the pointer of the Device structure of which the volume belongs to */

    /* physical sector numbers */
    SECTNUM firstBlock;            /* first block of the data area (from the beginning of the media) */
    SECTNUM lastBlock;             /* last usable block (from the beginning of the media) */

    /* logical sector number */
    SECTNUM rootBlock;             /* root block (from firstBlock) */

    char dosType;                  /* FFS/OFS, DIRCACHE, INTERNATIONAL */
    BOOL bootCode;                 /* TRUE if a floppy is bootable */
    int dataBlockSize;             /* 488 or 512 */

    char* volName;

    /* bitmap */
    long bitmapSize;                    /* number of blocks used to store the bitmap 
                                            (excluding the bitmapExtension blocks)         */
    SECTNUM *bitmapBlocks;              /* bitmap blocks pointers (excluding bitmap extensions blocks) */
    struct bBitmapBlock* *bitmapTable;  /* stores the bitmap blocks */
    BOOL *bitmapBlocksChg;              /* bitmapBlocksChg[i] is TRUE if bitmapTable[i} has changed,
                                            and need to be written at bitmapBlocks[i]                  */

    SECTNUM curDirPtr;      /* number of the current working directory */
}

If vol is one Volume structure returned by adfMount() :

  • The devType is vol->dev->devType.
  • The dosType is OFS or FFS (exclusive), and may have the DIRCACHE and INTERNATIONAL modes enabled. Uses isFFS(vol->dosType), isOFS(), isINTL() and isDIRCACHE() to determine it.
    Warning ! Even if isINTL() returns FALSE, if isDIRCACHE() is TRUE, the Volume is considered (like with AmigaDOS) as having the international mode enabled !

adfMount()

Syntax

struct Volume* adfMount(struct Device *dev, int nPart, BOOL readOnly)

Description

Mounts a designed volume (nPart) of the Device (dev), eventually with read only access (readOnly). The first partition is #0.

The current working directory is the root block.

Return values

The Volume, NULL in case of error.

Internals

  1. Read the bootblock to determine vol->dosType and vol->datablockSize.
  2. Read the rootblock, fills vol->curDirPtr
  3. Read and allocate the bitmap : vol->bitmapBlocks[], vol->bitmapTable[], vol->bitmapSize, vol->bitmapBlocksChg[].

adfUnMount()

Syntax

void adfUnMount(struct Volume *vol)

Description

Release a Volume. Free the bitmap structures.


adfCountFreeBlocks()

Syntax

long adfCountFreeBlocks(struct Volume *vol)

Description

Counts the free blocks of a Volume.

Return values

The number of free blocks.


adfInstallBootBlock()

Syntax

RETCODE adfInstallBootBlock(struct Volume* vol, unsigned char* code)

Description

Install a bootblock on a floppy disk. Won't work on any other device.

You must provide the 1024 bytes large bootblock.
Doesn't modify the initial 'DOS' header and dosType. Recalculates the checksum.

Return values

RC_OK, something different in case of error.


adfCreateHdFile()

Syntax

RETCODE adfCreateHdFile(struct Device* dev, char* volName, int volType)

Description

Create an hardfile on a dump file. The size of this file must be larger than 1802240 bytes, the size of an high density floppy dump.

Use adfCreateDumpDevice() the create the device passed to adfCreateHdFile().

Return values

RC_OK, something different in case of error.

Internals

The device is created with one volume, and dev->devType if filled with DEVTYPE_HARDFILE.


unadf-0.7.11a/Docs/api_env.html0000644000000000000000000001022310534557264014744 0ustar rootroot Environment

the Environment API


Typical usage

#include"adflib.h"


void MyVer(char *msg)
{
    fprintf(stderr,"Verbose [%s]\n",msg);
}


int main()
{
    BOOL boolPr = TRUE;

    adfEnvInitDefault();

    /* to use the dir cache blocks, default is FALSE */
    adfChgEnvProp(PR_USEDIRC, (void*)&boolPr);      // optional
	
    /* to override the verbose callback */
    adfChgEnvProp(PR_VFCT, MyVer);                  // optional

    adfEnvCleanUp();
}

adfEnvInitDefault()

Syntax

void adfEnvInitDefault()

Description

Initialise the library data structures and default values. Must be done before any other call to the library.

There is 4 callback functions which can be (and must be) overridden, the library must not write anything to the console.

  • The verbose messages redirection,
  • the warning messages redirection,
  • the error messages redirection (must stop the library)
  • The notification callback : when the current directory has changed.
  • The progress bar : this function is called with an int first set to 0. Then the value increases up to 100. It can be used to display a progress bar.
By default, those functions write a message to stderr.

Another environment property is the ability to use or not the dir cache blocks to get the content of a directory. By default, it is not used.

See adfChgEnvProp() to learn how to change those properties.

Internals

  1. Set the default values
  2. Prints the library version with the verbose callback.
  3. Allocate the native functions structure
  4. Calls adfInitNativeFct()

adfChgEnvProp()

Syntax

void adfChgEnvProp(int propertyName, void* new value)

Description

Change the default or lastest value of one of the environment property. The new value has the void*, this is the only way to transmit it for several types. A cast is made depending of the property name inside adfChgEnvProp().

Here's the list of the properties, and their types :

  • PR_VFCT, displays verbose messages, (void(*)(char*))
  • PR_WFCT, displays warning messages, (void(*)(char*))
  • PR_EFCT, displays error messages, (void(*)(char*))
  • PR_NOTFCT, directory object change notification, (void(*)(SECTNUM,int))
  • PR_USE_NOTFCT, toggle on/off (default=off=false), BOOL
  • PR_PROGBAR, progress bar, (void(*)(int))
  • PR_USE_PROGBAR, use progress bar (default=off), BOOL
    The functions that support 'progress bar' are : adfCreateFlop(), adfCreateHd(), adfCreateHdFile().
  • PR_RWACCESS, read (BOOL=false) or write (BOOL=true) operation, logical block and physical sector accessed, (void(*)(SECTNUM,SECTNUM,BOOL))
  • PR_USE_RWACCESS, use rwaccess (default=off), BOOL
  • PR_USEDIRC, use dircache blocks, BOOL (default=off).
For the non pointer types (int with PR_USEDIRC), you have to use a temporary variable. To override successfully a function, the easiest is to reuse the default function located in adf_env.c, and to change it for your needs.


adfEnvCleanUp()

Syntax

void adfEnvCleanUp()

Description

Cleans up the environment.

Internals

Frees the native functions structure.

adfEnvCleanUp() : Obsolete

Syntax

void adfSetEnvFct( void(*eFct)(char*) error, void(*wFct)(char*) warning, void(*vFct)(char*) verbose, void(*notFct)(SECTNUM,int) notify )

Obsolete : use adfChgEnvProp() instead.


adfGetVersionNumber()

Syntax

char* adfGetVersionNumber()

Description

Returns the current numeric ADFlib version.


adfGetVersionDate()

Syntax

char* adfGetVersionDate()

Description

Returns the date of the ADFlib current version.

unadf-0.7.11a/Docs/api_native.html0000644000000000000000000001335610534557264015454 0ustar rootroot Native

the Native API


Introduction

By default, the library is compiled to manage .ADF files (dump files) and plateform specific real devices like harddisk or removable disks (called native devices).
At compile time, you can choose between available platforms like Win32/Intel for example. At run-time, it is possible to mount a dump device or a real device, several times.

To add a new plateform support into ADFlib, you must write your own files adf_nativ.h and adf_nativ.c for that platform. This driver is the link between the native API of the library and the platform specific functions to access the hardware.

The templates for those files are in Generic/.

The native API consists of :

1. The natives functions :

  • RETCODE adfInitDevice(struct Device*, char*)
  • RETCODE adfReleaseDevice(struct Device*)
  • RETCODE adfNativeReadSector(struct Device*, long, int, unsigned char*)
  • RETCODE adfNativeWriteSector(struct Device*, long, int, unsigned char*)
  • BOOL adfIsDevNative(char*)
  • void adfInitNativeFct()
2. And two data structures devoted to native devices management :
  • struct nativeFunctions stored in the library environment,
  • struct nativeDevice stored in the struct Device structure.
The author of the driver defines the nativeDevice structure and writes the expected functions below, with the expected parameters and the expected behaviours.

At the environment initialisation, a pointer of each function is stored in the nativeFunctions structure with adfInitNativeFct().

Here's how, for example, adfMountDev() call a native function : adfInitDevice() :


struct Device* adfMountDev(char* filename)
{
struct nativeFunctions *nFct;
struct Device* dev;
  
/* 'dev' memory allocation */

/* gets the native function pointers */
nFct = (struct nativeFunctions*)adfEnv.nativeFct; /* was of type void* */

/* only once ! */
dev->isNativeDev = (*nFct->adfIsDevNative)(filename);

/* choose dump or a real device initialisation */
if (dev->isNativeDev)
    (*nFct->adfInitDevice)(dev, filename);
else
    adfInitDumpDevice(dev, filename);

...



Data structures

struct nativeFunctions{
    /* function pointers */
    RETCODE (*adfInitDevice)(struct Device*, char*);
    RETCODE (*adfNativeReadSector)(struct Device*, long, int, unsigned char*);
    RETCODE (*adfNativeWriteSector)(struct Device*, long, int, unsigned char*);
    BOOL (*adfIsDevNative)(char*);
    RETCODE (*adfReleaseDevice)();
};

Those functions are detailed above.

struct nativeDevice{
    /* private to native functions, never used in the library, only in native functions */
    /* for the dump devices, this structure contains one field : FILE *fd */
};


adfInitDevice()

Syntax

RETCODE adfInitDevice(struct Device* device, char* name)

You can choose another name, but the same parameters types and number, and the same return type.

Description

Initialise the native device.

Return values

RC_OK if everything went allright, something else otherwise.

Template

RETCODE adfInitDevice(struct Device* dev, char* name)
{
    struct nativeDevice* nDev;

    /* the type was 'void*' */
    nDev = (struct nativeDevice*)dev->nativeDev;

    nDev = (struct nativeDevice*)malloc(sizeof(struct nativeDevice));
    if (!nDev) {
        (*adfEnv.eFct)("myInitDevice : malloc");
        return RC_ERROR;
    }
    dev->nativeDev = nDev;

/*
 * specific device operations
 *
 * you MUST set the 'dev->size' field with the length in bytes of the physical media
 */

    return RC_OK;
}

adfNativeReadSector()

Syntax

RETCODE adfNativeReadSector(struct Device* device, long n, int size, unsigned char* buf)

You can choose another name, but the same parameters types and number, and the same return type.

Description

Move to 512*n bytes from the beginning of the media, and read size bytes into the buf buffer.


adfNativeWriteSector()

Syntax

RETCODE adfNativeWriteSector(struct Device* device, long n, int size, unsigned char* buf)

You can choose another name, but the same parameters types and number, and the same return type.

Description

Move to 512*n bytes from the beginning of the media, and write size bytes into the buf buffer.


adfReleaseDevice()

Syntax

RETCODE adfReleaseDevice(struct Device* device)

You can choose another name, but the same parameters types and number, and the same return type.

Description

Release the device.

adfIsDevNative()

Syntax

RETCODE adfIsDevNative(char* name)

You can choose another name, but the same parameters types and number, and the same return type.

Description

TRUE is the name points out a native device, FALSE otherwise.

adfInitDevice()

Syntax

RETCODE adfInitDevice(struct Device* device, char* name)

You can choose another name, but the same parameters types and number, and the same return type.

Description

Initialise the nativeFunctions structure with the native functions addresses.
unadf-0.7.11a/Docs/api_index.html0000644000000000000000000000136510534557264015272 0ustar rootroot The ADFlib Developpers documentation

the ADFlib API


  • Device : create and mount/unmount harddisk, floppydisk, .ADF, hardfiles,
  • Volume : create and mout/unmount volumes
  • Directory : list, create, change of directories,
  • File : create, read and write files,
  • Environment : initialize and shutdown the library, control its behaviour,
  • Salvage : undeletion, recovery,
  • Native API : how to write real devices drivers on your OS,

unadf-0.7.11a/Docs/api_dir.html0000644000000000000000000001234610534557264014742 0ustar rootroot Directory

the Directory API


Data structures


/* entry types */

#define ST_DIR     2
#define ST_FILE   -3


struct Entry{
    int type;              /* type of the entry */
    char *name;            /* name */
    SECTNUM sector;        /* sector pointer */
    char *comment;         /* optional comment */
    unsigned long size;    /* file size, 0 for a directory */
    long access;           /* RWEDAPSH access rights */

    int year, month, day;  /* date */
    int hour, min, sec;    /* hour */
}


/* general purpose list used to stored directory entries */
struct List{
    void *content;         /* Filled with struct Entry* type */
    struct List *subdir;   /* If the cell content is a dir, its entries list */
                           /*  is stored here, else filled with NULL   */
    struct List *next;     /* Next cell */
}

adfGetDirEnt()

Syntax

struct List* adfGetDirEnt(struct Volume* vol, SECTNUM dir )
equivalent to
struct List* adfGetRDirEnt(struct Volume* vol, SECTNUM dir, FALSE )

Description

Returns a linked list which contains the entries of one directory.

Return values

The list, NULL in case of error.

Examples

struct List *list, *cell;
struct Entry *entry;

/* saves the head of the list */
cell = list = adfGetDirEnt(vol,vol->curDirPtr);

/* while cell->next is NULL, the last cell */
while(cell) {
    entry = (struct Entry*)cell->content;
    printf("%s %ld\n", entry->name, entry->sector);
    cell = cell->next;
}

/* frees the list and the content */
adfFreeDirList(list);




adfGetRDirEnt()

Syntax

struct List* adfGetRDirEnt(struct Volume* vol, SECTNUM dir, BOOL recursive )

Description

Returns a linked list which contains the entries of one directory.

Return values

The list, NULL in case of error.

Examples


#define TRUE 1

int main()
{

struct List *list, *cell;
struct Entry *entry;

...

/* saves the head of the list */
cell = list = adfGetRDirEnt(vol,vol->curDirPtr,TRUE);

/* prints the tree */
printTree(cell);

/* frees the list and the content */
adfFreeDirList(list);

...

}

/* print the directories tree. recursive */
printTree(struct List* tree)
{
    while(tree) {
        entry = (struct Entry*)cell->content;
        printf("%s %ld\n", entry->name, entry->sector);
        if (tree->subdir!=NULL)
            printTree(tree->subdir)
        tree = tree->next;
    }
}



adfChangeDir()

Syntax

RETCODE adfChangeDir(struct Volume* vol, char *dirName)

Description

Change the current working directory to the new one (dirName).

Return values

RC_OK, something different in case of error.


adfParentDir()

Syntax

RETCODE adfParentDir(struct Volume* vol)

Description

Change the current working directory to its parent directory. If the current directory is the root of the filesystem ('/'), nothing happens.

Return values

RC_OK, something different in case of error.


adfCreateDir()

Syntax

RETCODE adfCreateDir(struct Volume* vol, SECTNUM parent, char* dirName)

Description

Creates a new directory (dirName) into the specified directory (parent).

Return values

RC_OK, something different in case of error.


adfRemoveEntry()

Syntax

RETCODE adfRemoveEntry(struct Volume *vol, SECTNUM parent, char *name)

Description

Removes a entry (a file or an empty directory) from one directory (parent).

Return values

RC_OK, something different in case of error.


adfFreeDirList()

Syntax

void adfFreeDirList(struct List* list)

Description

Frees a linked list or a tree of directory entries.


adfAccess2String()

Syntax

char* adfAccess2String(long access)

Description

Converts the access rights from long to char*.

Return values

A C string which represents the access rights.


adfRenameEntry()

Syntax

RETCODE adfRenameEntry(struct Volume* vol, SECTNUM oldDir, char* old, SECTNUM newDir, char* new)

Description

Changes the name of the entry old located in the oldDir into the name new, located into the newDir directory.


printEntry()

Syntax

void printEntry(struct Entry* entry)

Description

Do no use this function (not an adf one), but you can use its code to learn how to display a directory entry (in adf_dir.c).


unadf-0.7.11a/Docs/api_file.html0000644000000000000000000001242010534557264015074 0ustar rootroot File

the File API

Data structures

Warning ! None of the fields of the structure below must be modified directly. In this case, i can not tell how will behave the library. Unless specified, read access is of course allowed.

The dynamic memory allocation/releasing is done by the library (i hope :).

struct File {
    struct Volume *volume;            // pointer to the volume

    struct bFileHeaderBlock* fileHdr; // the header block
    void *currentData;                // current data block
    struct bFileExtBlock* currentExt; // current data extension block

    long nDataBlock;                  // number of current data blocks
    SECTNUM curDataPtr;               // pointer to the current data block
    unsigned long pos;                // file pos

    int posInDataBlk;                 // index in a datablock
    int posInExtBlk;                  // index in a file header or file extension block
    BOOL eof;                         // TRUE is the last byte has been read, use adfendOfFile() 
    BOOL writeMode;                   // if the adfOpenFile() mode is "w"
    };


adfOpenFile()

Syntax

struct File* adfOpenFile(struct Volume* vol, char* name, char* mode);

Description

Opens the file with the name name which is located in the current working directory of the vol volume.
The allowed mode are "r" and "w". If the mode is "w", the file mustn't already exists, otherwise an error occurs.

Some basic access permissions are just checked for now.

Return values

The File structure, ready to be read or wrote.
NULL if an error occurs : file not found with "r", or file already exists with "w".

Internals


adfFlushFile()

Syntax

void adfFlushFile(struct File* file);

Description

Flushes the datablocks on disk.


adfCloseFile()

Syntax

void adfCloseFile(struct File* file)

Description

Calls adfFlushFile() and frees the file structure.


adfFileRealSize()

Syntax

long adfFileRealSize(unsigned long size, int blockSize, long* dataN, long* extN);

Description

Returns the real size in blocks of a file which the given size. It does not taking into account the new dircache that -may- be allocated.

The blockSize must be 488 or 512. This information is located in the datablockSize of the Volume structure.

If the pointers dataN and extN aren't NULL, the number of data blocks and file extension blocks are returned.


adfReadFile()

Syntax

long adfReadFile(struct File* file, long n, unsigned char* buffer)

Description

Read n bytes from the given file into the buffer buffer.

Use adfEndOfFile() to check if the end of the file is reached or not.

Example


#include"adflib.h"


struct File* file;
FILE* out;
long n;
unsigned char buf[600];

/* a device and a volume 'vol' has been successfully mounted */


/* opens the Amiga file */
file = adfOpenFile(vol, "mod.and.distantcall","r");
if (!file) { /* frees resources and exits */  };

/* opens the output classic file */
out = fopen("mod.distant","wb");
if (!out) { adfCloseFile(file); /* ... */ };
    
/* copy the Amiga file into the standard file, 600 bytes per 600 bytes */
len = 600;
n = adfReadFile(file, len, buf);
while(!adfEndOfFile(file)) {
    fwrite(buf, sizeof(unsigned char), n, out);
    n = adfReadFile(file, len, buf);
}
/* even if the EOF is reached, some bytes may need to be written */
if (n>0)
    fwrite(buf, sizeof(unsigned char), n, out);

/* closes the standard file */
fclose(out);

/* closes the Amiga file */
adfCloseFile(file);

Returned values

The number of bytes really read.


adfEndOfFile()

Syntax

BOOL adfEndOfFile(struct File* file)

Description

TRUE if the end of the file file is reached.


adfWriteFile()

Syntax

long adfWriteFile(struct File* file, long n, unsigned char* buffer)

Description

Writes n bytes from the given buffer into the file file.

Example


#include"adflib.h"

struct File* file;
FILE* in;

/* a device and a volume 'vol' has been successfully mounted */


file = adfOpenFile(vol, "moon_gif", "w");
if (!file) { /* error handling */ };

in = fopen( argv[2],"rb");
if (!out) { adfCloseFile(file); /* error handling */ };
    
len = 600;
n = fread(buf,sizeof(unsigned char),len,out);
while(!feof(out)) {
    adfWriteFile(file, n, buf);
    n = fread(buf,sizeof(unsigned char),len,out);
}
if (n>0)
    adfWriteFile(file, n, buf);

fclose(out);

adfCloseFile(file);

Returned values

The number of bytes really wrote.


unadf-0.7.11a/Faq/0000755000000000000000000000000010554754210012246 5ustar rootrootunadf-0.7.11a/Faq/adf_info.txt0000644000000000000000000024244510554753630014574 0ustar rootroot------------------------------------------------------------------------ The .ADF (Amiga Disk File) format FAQ Laurent Clvy, lclevy@club-internet.fr v1.11 - March 5th, 2005 ------------------------------------------------------------------------ / This document describes the .ADF file format. An Amiga Disk File is a sector per sector dump of an Amiga formatted disk. The intent is to explain in detail how the Amiga stores files and directories on floppy and hard disks. A set of C routines (ADFlib) will be supplied to manage the ADF format. / ------------------------------------------------------------------------ 0. Changes <#p0> 1. Introduction <#p1> * 1.1 Disclaimer and Copyright <#p11> * 1.2 Feedback, updates <#p12> * 1.3 Conventions <#p13> * 1.4 Acknowledgements <#p14> 2. How bytes are physically read from and written to a disk ? <#p2> * 2.1 What is MFM encoding/decoding ? <#p21> * 2.2 What is the MFM track format ? <#p22> * 2.3 What is the MFM sector format ? <#p23> * 2.4 How to decode MFM data ? <#p24> 3. What is the Amiga floppy disk geometry ? <#p3> 4. What is the logical organisation of an Amiga volume ? <#p4> * 4.1 What is a Bootblock ? <#p41> * 4.2 What is a Rootblock ? <#p42> o 4.2.1 How to find the first sector of an entry ? <#p421> o 4.2.2 How to list directory entries ? <#p422> o 4.2.3 How to compute the checksum ? <#p423> * 4.3 How are the free and used block lists managed ? <#p43> * 4.4 How are files stored ? <#p44> * 4.5 How are directories stored ? <#p45> * 4.6 How are links implemented in AmigaDOS ? <#p46> o 4.6.1 Hard links <#p461> o 4.6.2 Soft links <#p462> * 4.7 How are the blocks associated with the dircache mode ? <#p47> 5. How does a blank disk look like ? <#p5> * 5.1 A minimal blank floppy disk <#p51> * 5.2 A 'Bootable' floppy disk <#p52> * 5.3 A directory cache mode floppy disk <#p53> * 5.4 International mode <#p54> 6. The structure of a hard disks ? <#p6> * 6.1 What is the Rigid Disk Block ? <#p61> * 6.2 How are bad blocks managed ? <#p62> * 6.3 How are partitions stored ? <#p63> * 6.4 What are FSHD blocks ? <#p64> * 6.5 What are LSEG blocks ? <#p65> 7. The Hard file : a big floppy dump file <#p7> 8. Advanced information <#p8> 9. References and links <#p9> 10. C Routines : the ADF Library <#p10> 11. Other Amiga file systems <#p11> ------------------------------------------------------------------------ 0. Changes Since 1.10 (November 27th, 2001) * Links updated * Amiga Floppy Reader link removed. The project seems cancelled. Since 1.09 (3. Sep 1999) * [add] ADFlib is used by ADFview from Bjarke Viksoe * [chg] URLs fixes Since 1.08 (2. August 1999) * [chg] fix: the hashvalue function was buggy on some rare name * [chg/add] suggestions (last ones) by Hans-Joachim. Since version 1.07 (27. May 1999) * [chg] suggestions by Jrg Strohmayer (author of aminet:disk/moni/DiskMonTools.lha) * [chg] suggestions by Hans-Joachim Widmaier * [chg] minor additions to the MFM track format, from an online version of "RKRM : Libraries and Devices, appendix C" Since version 1.06 (2. May 1999), by Heiko Rath (hr@brewhr.swb.de) : * [chg] Minor spelling corrections * [chg] Blocksizes other than 512 bytes documented * [chg] DosEnvVector extended * [add] link to the Amiga Floppy Reader project Since version 1.04 (16. January 1999) : * [chg] Corrections suggested by Hans-Joachim Widmaier (Linux affs maintainer) * [add] The WinUAE hardfile format section is starting Since version 0.9 (28. May 1997) : * [add] HTML version with figures * [add] Hard disk section added * [chg] Correction about DIRC and INTL modes (section 4.1 <#p41>) * [add] The whole rewritten *ADF library* is released (0.7.8) and used within the *ADFOpus* project (New site Gary Harris, Old site Dan Sutherland) * [chg] The bitmap checksum algorithm is the same as the rootblock algorithm * [add] Allowed/forbidden characters in volume and file names, 4GB limit * [add] how to rename an entry ------------------------------------------------------------------------ 1. Introduction In this document, we will describe how the AmigaDOS is (was?) managing storage media, from the magnetic layer to the files and directories layer. With *physical layer*, I'm talking about the way bytes are physically stored on a magnetic surface, with the RLL or MFM encoding. The next layer, according to the 'most physical' to 'most conceptual' order, is the *partitions layer* : this is how the AmigaDOS is managing media with more then one partition, like Zip disks or hard disks. The next and last layer is the *volume layer* : where the files and directories are stored. The physical layer is described in the 2nd chapter, The volume layer is the biggest part of the document (4th and 5th chapters), since it's the most interesting, The partitions layer is explained in the 6th chapter. Let's continue with more conventional things in an introduction. ------------------------------------------------------------------------ 1.1 Disclaimer and copyright This document is Copyright (C) 1997-1999 by Laurent Clvy, but may be freely distributed, provided the author name and addresses are included and no money is charged for this document. This document is provided "as is". No warranties are made as to its correctness. Amiga and AmigaDOS are registered Trademarks of Gateway 2000. Macintosh is a registered Trademark of Apple. ------------------------------------------------------------------------ 1.2 Feedback, updates If you find any mistakes in this document, have any comments about its content, feel free to send me an e-mail. Corrections are very welcome. You can find new versions of this document at : * The ADFlib page : http://lclevy.free.fr/adflib/adf_info.html ------------------------------------------------------------------------ 1.3 Conventions In this document, hexadecimal values use the C syntax : for example 0x0c is the decimal value 12. Byte ordering Since the Amiga is a 680x0 based computer, integers that require more than one byte are stored on disk in 'Motorola order' : the most significant byte comes first, then the less significant bytes in descending order of significance (MSB LSB for two-byte integers, B3 B2 B1 B0 for four-byte integers). This is usually called *big endian* byte ordering. The Intel based PCs are using the *little endian* byte ordering. Vocabulary A 'word' or 'short' is a 2-byte (16 bits) integer, a 'long' a 4-byte (32 bits) integer. Values are unsigned unless otherwise noted. A 'block' in this document will be 512 consecutive bytes on disk, unless noted otherwise, the variable 'BSIZE' will denote the blocksize. The word 'sector' and 'block' will be used as synonyms here, even if 'sector' is usually related to the physical side, and the 'block' to the logical side. This is because the AmigaDOS can only handle one sector per block. Some other Unix filesystems can have more then one sector per block. A block pointer is the number of this block on the disk. The first one is the #0 block. There are 'logical' and 'physical' block pointers. 'Logical' ones are related to the start of one volume, 'physical' one are related to the start of a physical media. If a volume starts at the #0 physical sector, a physical pointer and a logical pointer is the same thing, like with floppies. A simple definition of 'Hashing' could be : "a method to access tables : given a number or a string, a hash function returns an index into an array". This definition is correct for this document, but there is a lot of other hashing methods, that might be far more complex. Linked lists are cell-oriented data structures. Each cell contains a pointer to the next or previous cell or both, the last cell pointer is null. C example : struct lcell { char name[10]; /* contains next cell adress, or NULL if this cell is the last */ struct lcell *next_cell; }; Block names begin with a capital (Rootblock). Field names are noted between quotes ('field_name'). All formats are described as tables, one row per field. Here is an example with the beginning of the well known GIF format : offset type length name comments ---------------------------------------------------------- 0 char 3 signature 'GIF' 3 char 3 version '87a' or '89a' 6 short 1 screen width (little endian) 8 short 1 screen height (little endian) The .ADF format is the format created and used by the -incredible- UNIX Amiga Emulator (UAE), written by Berndt Schmitt. The home page is here : http://www.freiburg.linux.de/~uae/ The .ADF files can be created with the program *transdisk*. ------------------------------------------------------------------------ 1.4 Acknowledgements I would to thank here again the people who take time to send me corrections, suggestions and opinions about this document : * Hans-Joachim Widmaier for the -very detailed- review and suggestions, * Dan Sutherland (dan@chromerhino.demon.co.uk) for the suggestions and ideas, * Jorg Strohmayer (see Aminet:disk/moni/DiskMonTools.lha, his DiskMonTools utility) * Heiko Rath (hr@brewhr.swb.de) for some modifications. * Jean Yves Peterschmitt (jypeter@lmce.saclay.cea.fr) for the review, * Thomas Kessler (tkessler@ra.abo.fi) for the bootcode flag note. 2. How are bytes physically read from / written to a disk ? The following part deals with the way the Amiga disk controller accesses the magnetic medium. If you only want to understand the .ADF format, you don't need to read this part. Information is written on disk with magnetic fields. Magnetic fields can be made 'on' or 'off'. But the read/write heads are not capable of detecting directly if a field is on or off. An encoding is used to store memory bits on the medium. The CHANGE of fields polarisation will indicate if the bit is 1 or 0. For Amiga floppy disks (and PC floppies), the encoding scheme is MFM (Modified frequency modulation). Notes on the Amiga floppy disk controller : The Amiga floppy disk controller (FDC) which is called 'Paula' is very flexible. It is capable of reading/writting Amiga/PC/Macintosh/AppleII/C64 3.5 inches and 5.25 inches floppy disks. Paula can read a variable number of bytes from disk, the PC FDC can't. The PC FDC uses the index hole to find the beginning of a track, Paula uses a synchronization word. The Macintosh uses GCR encoding instead of MFM. In fact, Paula is simpler than the PC FDC because it does not perform automatically the decoding just after the read operation, and the encoding just before the write operation : it must be done by software. The MFM decoding/encoding is done by hardware with the PC FDC, the Amiga can do GCR or MFM decoding/encoding because it's done with the CPU. In some versions of the AmigaDOS, the decoding/encoding is made by the Blitter custom chip. Classic PC FDCs *can't read Amiga floppy disks* even if they are MFM encoded on a 3.5 inch floppy, because they can not find the beginning of a track. This is why the .ADF format has been created. However, a custom FDC available on PC machines is capable of reading/writing Amiga, PC, Macintosh, Atari and C64 floppies !!! This is CatWeasel : link Paula parametrization for Amiga disks : * MFM encoding * Precompensation time : 0 nanoseconds * Controller clock rate : 2 microseconds per bit cell * Synchronization value : 0x4489 Paula is able to put the read/write heads on a cylinder, and is able to read with the lower or upper side head. A track of 0x1900 words is usually read. ------------------------------------------------------------------------ 2.1 What is MFM encoding/decoding ? The MFM decoding is made by the Amiga CPU, not by Paula. This allows custom encoding, to protect floppies against copying for example. Here follows the MFM encoding scheme : user's data bit MFM coded bits --------------- -------------- 1 01 0 10 if following a 0 data bit 0 00 if following a 1 data bit User data long words are split in two parts, a part with even bits part first, followed by a part with odd bits. Once encoded, the amount of data stored doubles. The MFM decoding will transform magnetic fields into computer usuable bits. The encoding process will take one long (user's data), and produces two longs (MFM coded longs): one for the even bits of the user long, a second for the odd bits of the user long. Vice versa, the decoding process will take the half of two MFM longs to produce one user's long. ------------------------------------------------------------------------ 2.2 What is the MFM track format ? Paula will search two synchronization words, and then read 0x1900 words of data. We will call those 0x1900 words a 'MFM track'. There are 80 cylinders on a Amiga floppy disk. Each cylinder has 2 MFM tracks, 1 on each side of the disk. Double density (DD) disks have 11 sectors per MFM track, High density (HD) disks have 22 sectors. So a MFM track consists of 11/22 MFM encoded sectors, plus inter-track-gap. Note that sectors are not written from #0 to #10/21, you must use the 'info' field to restore the correct order when you read the tracks. Each MFM track begins with the first sector, and ends with the end of the last sector. Each sector starts with 2 synchronization words. The synchronization value is 0x4489. ------------------------------------------------------------------------ 2.3 What is the MFM sector format ? From RKRM: "Per-track Organization: Nulls written as a gap, then 11 or 22 sectors of data. No gaps written between sectors." There are brut data and encoded data. Brut data (also called MFM data) doesn't need to be decoded, this is the synchronization data, the header checksum and data checksum. The encoded parts are 'header' and 'data'. Here it comes : 00/0x00 word 2 MFM value 0xAAAA AAAA (when decoded : two bytes of 00 data) SYNCHRONIZATION 04/0x04 word 1 MFM value 0x4489 (encoded version of the 0xA1 byte) 06/0x06 word 1 MFM value 0x4489 HEADER 08/0x08 long 1 info (even bits) 12/0x0c long 1 info (odd bits) decoded long is : 0xFF TT SS SG 0xFF = Amiga v1.0 format TT = track number ( 3 means cylinder 1, head 1) SS = sector number ( 0 upto 10/21 ) sectors are not ordered !!! SG = sectors until end of writing (including current one) Example for cylinder 0, head 1 of a DD disk : 0xff010009 0xff010108 0xff010207 0xff010306 0xff010405 0xff010504 0xff010603 0xff010702 0xff010801 0xff01090b 0xff010a0a the order of the track written was sector 9, sector 10, sector 0, sector 1 ... (see also the note below from RKRM) Sector Label Area : OS recovery info, reserved for future use 16/0x10 long 4 sector label (even) 32/0x20 long 4 sector label (odd) decoded value is always 0 This is operating system dependent data and relates to how AmigaDOS assigns sectors to files. Only available to 'trackdisk.device', but not with any other floppy or hard disk device. END OF HEADER 48/0x30 long 1 header checksum (even) 52/0x34 long 1 header checksum (odd) (computed on mfm longs, longs between offsets 8 and 44 == 2*(1+4) longs) 56/0x38 long 1 data checksum (even) 60/0x3c long 1 data checksum (odd) (from 64 to 1088 == 2*512 longs) DATA 64/0x40 long 512 coded data (even) 576/0x240 long 512 coded data (odd) 1088/0x440 END OF DATA Note from RKRM : The track number and sector number are constant for each particular sector. However, the sector offset byte changes each time we rewrite the track. The Amiga does a full track read starting at a random position on the track and going for slightly more than a full track read to assure that all data gets into the buffer. The data buffer is examined to determine where the first sector of data begins as compared to the start of the buffer. The track data is block moved to the beginning of the buffer so as to align some sector with the first location in the buffer. Because we start reading at a random spot, the read data may be divided into three chunks: a series of sectors, the track gap, and another series of sectors. The sector offset value tells the disk software how many more sectors remain before the gap. From this the software can figure out the buffer memory location of the last byte of legal data in the buffer. It can then search past the gap for the next sync byte and, having found it, can block move the rest of the disk data so that all 11 sectors of data are contiguous. Example: The first-ever write of the track from a buffer looks like this: |sector0|sector1|sector2|......|sector10| sector offset values: 11 10 9 ..... 1 (If I find this one at the start of my read buffer, then I know there are this many more sectors with no intervening gaps before I hit a gap). Here is a sample read of this track: |sector9|sector10||sector0|...|sector8| value of 'sectors till end of write': 2 1 .... 11 ... 3 result of track re-aligning: |sector9|sector10|sector0|...|sector8| new sectors till end of write: 11 10 9 ... 1 so that when the track is rewritten, the sector offsets are adjusted to match the way the data was written. ------------------------------------------------------------------------ 2.4 How to decode MFM data ? C algorithm : #define MASK 0x55555555 /* 01010101 ... 01010101 */ unsigned long *p1; /* MFM coded data buffer (size == 2*data_size) */ unsigned long *q; /* decoded data buffer (size == data_size) */ unsigned long a,b; unsigned long chksum; int data_size; /* size in long, 1 for header's info, 4 for header's sector label */ int count; chksum=0L; /* the decoding is made here long by long : with data_size/4 iterations */ for (count=0; countBootblocks * BSIZE) - 12 ------------------------------------------------------------------------------- The DiskType flag informs of the disk format. * OFS = Old/Original File System, the first one. (AmigaDOS 1.2) * FFS = Fast File System (AmigaDOS 2.04) * INTL = International characters Mode (see section 5.4 <#p54>). * DIRC = stands for Directory Cache Mode. This mode speeds up directory listing, but uses more disk space (see section 4.7 <#p47>). The Old filesystem may have the international and dircache mode enabled. If the international mode is enabled, the bit #1 is set. If the dircache is enabled, its flag is set (bit #2), *and the international mode is also enabled, but the related flag (bit #1) will stay cleared*. The correct values for flag are therefore : 0 (OFS), 1 (FFS), 2 (OFS/INTL), 3 (FFS/INTL), 4 (OFS/DIRC&INTL), 5 (FFS/DIRC&INTL). There are few differences between the two file systems : * OFS Datablock stores BSIZE-24 bytes (i.e. normally 488 bytes at most frequently used BSIZE of 512 bytes), FFS stores BSIZE bytes. * FFS supports directory caching, links and international mode, * the FFS is faster than OFS. If the Bootblock starts with the three characters 'PFS', another filesystem is used in place of AmigaDOS : the Professional File System. If the checksum and the DiskType are correct, the system will execute the bootblock code, at boot time, of course :-). The Bootblock code is optional, see 5.2 <#p52> section. The Bootblock checksum algorithm follows : * in 68000 assembler : lea bootbuffer,a0 move.l a0,a1 clr.l 4(a1) ;clear the checksum move.w #(BOOTBLOCKSIZE/4)-1,d1 ;for floppy disks = 1024 ;for hd = (DosEnvVec->Bootblocks * BSIZE) moveq #0,d0 lpchk: add.l (a0)+,d0 ;accumulation bcc.s jump ;if carry set, add 1 to checksum add.l #1,d0 jump: dbf d1,lpchk ;next long word not.l d0 move.l d0,4(a1) ;new checksum * in C (version 1): #include #define Short(p) ((p)[0]<<8 | (p)[1]) #define Long(p) (Short(p)<<16 | Short(p+2)) unsigned long newsum,d; unsigned char buf[BOOTBLOCKSIZE]; /* contains bootblock */ /* for floppy disks = 1024, */ /* for hard disks = (DosEnvVec->Bootblocks * BSIZE) */ int i; memset(buf+4,0,4); /* clear old checksum */ newsum=0L; for(i=0; i.? and accented like are allowed. The date fields in the root block (and other blocks) are structured in the form of DAYS, MINS and TICKS. The DAYS field contains the number of days since January 1. 1978. MINS is the number of minutes that have passed since midnight and TICKS are expressed in 1/50s of a second. A day value of zero is considered illegal by most programs. The r_date / r_min / r_ticks fields are updated to the last recent change of the root directory of this volume. The v_date / v_min / v_ticks fields are updated whenever any change was made to this volume, not just the root directory. The c_date / c_min / c_ticks fields contain the date and time when this volume was initialized (i.e. formatted) and is not changed during its lifetime. Some date constraints : 0 <= Mins < 60*24, 0 <= Ticks < 50*60 The Amiga filesystem does not have an inherent year 2000 problem. If you want to know more about Y2K and the Amiga, you might take a look at : http://www.amiga.com . 4.2.1 How to find the first sector of a directory entry ? Given the name of a file/directory/link you first have to compute its hash value with this algorithm : * The hash function : #include int HashName(unsigned char *name) { unsigned long hash, l; /* sizeof(int)>=2 */ int i; l=hash=strlen(name); for(i=0; i The *toupper()* function is the one thing that distinguishes international from non-international filesystems. There was a bug in old AmigaDOS versions for this function applied to international caracters (ASCII codes > 128). A specific toupper() function (see section 5.4 <#p54>) was then created available with the 'international mode'. The hash value is then used to access HashTable ('ht' field in Rootblock/Directory block). HashTable[ HashValue ] contains the number of the first block of your object (File header block, Directory block or Link block). But different names can result in the same HashValue. If more then one name has the same HashValue, the other blocks (for files and directory only) are stored in a chained list. This linked list starts at the 'next_hash' field of the File header or Directory block. For example : 'file_1a', 'file_24' and 'file_5u' have the same hash value. Here follows the method to find the requested block : HashValue = HashName( name ); name=uppercase(name); nsector = Hashtable[ HashValue ]; if (nsector != 0) { sector=Load(nsector); /* reads the 'nsector' sector */ sector.name = uppercase(sector.name); /* * follows the 'same HashValue' chained list if needed */ while ( sector.name != name and sector.Next_hash != 0) { sector = Load(nsector); sector.name = uppercase(sector.name); } if (sector.name != name) puts("File/Dir not found"); } else puts("File/Dir not found"); // this code only works with non international mode disks // see section 5.4 <#p54> Figure : HashTable and Directory content Filenames characters can be lowercase and uppercase, but as shown in the Hash function, are not case sensitive. If, for a new entry, the value at hashTable[hashvalue] is different than 0, the new sector pointer will be stored in the last entry of the same-hashvalue-linked-list. It is necessary to check if the entry name already exists in this directory. In one word, in the same-hashValue list, the addition is made at the tail, not the head. Jorg tells the list is instead sorted by block number. 4.2.2 How to list all the directory entries ? Look through the whole HashTable and follow the same 'HashValue' linked lists if they exist. 4.2.3 How to compute the checksum ? #define Short(p) ((p)[0]<<8 | (p)[1]) #define Long(p) (Short(p)<<16 | Short(p+2)) unsigned long newsum; unsigned char buf[BSIZE]; /* contains rootblock */ int i; memset(buf+20,0,4); /* clear old checksum */ newsum=0L; for(i=0; i<(BSIZE/4); i++) newsum+=Long(buf+i*4); newsum=-newsum; /* negation */ This checksum algorithm works for most block types except for Bootblock. The bitmap table ('bm_pages[]') stores one or several pointers to Bitmap blocks. The first pointer is at index 0. ------------------------------------------------------------------------ 4.3 How are the free and used block lists managed? Bitmap blocks contain information about free and allocated blocks. One bit is used per block. If the bit is set, the block is free, a cleared bit means an allocated block. Bootblock allocation (2 for floppy, for hard disks the value can be found at DOSEnvVec->Bootblocks) is not stored in bitmap. Bitmap consists of longs, each describing the status of 32 blocks, where bit 0 corresponds to the lowest block number. * Bitmap block (BSIZE bytes), often at rootblock+1 ------------------------------------------------------------------------------- 0/0x00 long 1 checksum normal algorithm 4/0x04 long (BSIZE/4)-1 map ------------------------------------------------------------------------------- Here follows for a DD disk the relationship between bitmap and block number : block # long # bit # ------------------------------- 2 0 0 3 0 1 4 0 2 ... 33 0 31 34 1 0 35 1 1 ... 880 27 14 881 27 15 ... 1759 54 28 1760 54 29 This map is 1758 bits long (1760-2) and is stored on 54 full filled long and the first 30th bits of the 55th long. * What is the 'bm_ext' field in Rootblock ? If 25 bitmap blocks (which pointers are stored in the Rootblock) are not sufficient (for Hard Disks > ca. 50 Mbyte), the pointers to the further bitmap blocks are stored in so called bitmap extension blocks. The form a (surprise, surprise!) linked list, starting at the bm_ext field in the Rootblock. * Bitmap extension block (BSIZE bytes) (Hard disk only) ------------------------------------------------------------------------------- 0/0x00 ulong (BSIZE/4)-1 bitmap block pointers BSIZE- 4/0x04 ulong 1 next (0 for last) ------------------------------------------------------------------------------- The Bitmap extension linked list start at Rootblock with the 'bm_ext'. ------------------------------------------------------------------------ 4.4 How are files stored ? Files are comprised of a file header block, which contains information about the file (size, last access time, data block pointers, ...) and the data blocks, which contain the actual data. The file header block contains up to BSIZE/4-56 data block pointers (which amounts to 72 with the usual 512 byte blocks). If a file is larger than that, file extension blocks will be allocated to hold the data block pointers. File extension blocks are organised in a linked list, which starts in File header block ('extension' field). Figure : Chained lists of the blocks which store files * File header block (BSIZE bytes) ------------------------------------------------------------------------------------------------ 0/ 0x00 ulong 1 type block primary type T_HEADER (==2) 4/ 0x04 ulong 1 header_key self pointer (to this block) 8/ 0x08 ulong 1 high_seq number of data block ptr stored here 12/ 0x0c ulong 1 data_size unused (==0) 16/ 0x10 ulong 1 first_data first data block ptr 20/ 0x14 ulong 1 chksum same algorithm as rootblock 24/ 0x18 ulong * data_blocks[] data blk ptr (first at BSIZE-204 ) * = (BSIZE/4) - 56 BSIZE-200/-0xc8 ulong 1 UNUSED == 0 BSIZE-196/-0xc4 ushort 1 UID UserID BSIZE-194/-0xc4 ushort 1 GID GroupID BSIZE-192/-0xc0 ulong 1 protect protection flags (set to 0 by default) Bit If set, means If MultiUser FileSystem : Owner 0 delete forbidden (D) 1 not executable (E) 2 not writable (W) 3 not readable (R) 4 is archived (A) 5 pure (reetrant safe), can be made resident (P) 6 file is a script (Arexx or Shell) (S) 7 Hold bit. if H+P (and R+E) are set the file can be made resident on first load (OS 2.x and 3.0) 8 Group (D) : is delete protected 9 Group (E) : is executable 10 Group (W) : is writable 11 Group (R) : is readable 12 Other (D) : is delete protected 13 Other (E) : is executable 14 Other (W) : is writable 15 Other (R) : is readable 30-16 reserved 31 SUID, MultiUserFS Only BSIZE-188/-0xbc ulong 1 byte_size file size in bytes BSIZE-184/-0xb8 char 1 comm_len file comment length BSIZE-183/-0xb7 char 79 comment[] comment (max. 79 chars permitted) BSIZE-104/-0x69 char 12 UNUSED set to 0 BSIZE- 92/-0x5c ulong 1 days last change date (days since 1 jan 78) BSIZE- 88/-0x58 ulong 1 mins last change time BSIZE- 84/-0x54 ulong 1 ticks in 1/50s of a seconds BSIZE- 80/-0x50 char 1 name_len filename length BSIZE- 79/-0x4f char 30 filename[] filename (max. 30 chars permitted) BSIZE- 49/-0x31 char 1 UNUSED set to 0 BSIZE- 48/-0x30 ulong 1 UNUSED set to 0 BSIZE- 44/-0x2a ulong 1 real_entry FFS : unused (== 0) BSIZE- 40/-0x28 ulong 1 next_link FFS : hardlinks chained list (first=newest) BSIZE- 36/-0x24 ulong 5 UNUSED set to 0 BSIZE- 16/-0x10 ulong 1 hash_chain next entry ptr with same hash BSIZE- 12/-0x0c ulong 1 parent parent directory BSIZE- 8/-0x08 ulong 1 extension pointer to 1st file extension block BSIZE- 4/-0x04 ulong 1 sec_type secondary type : ST_FILE (== -3) ------------------------------------------------------------------------------------------------ As with volume names ':' and '/' are forbidden in file names. The number of blocks used to store a file depends on the filesystem used, OFS or FFS. If one file has 7 datablocks, the first is at datablock[71-0], the last at datablocks[71-6], and highseq equals to 7. For the OFS there are two ways of reading the contents of a file. First by traversing the linked list of data blocks that is pointed to in first_data (offset 16) and then following the pointers in each file data block. The other way of accessing the file data is by using the data_blocks[] table and going backwards through the data blocks listed there and then the File extension blocks. As the FFS doesn't contain extra information in the data blocks (no pointer list, no checksum) the only way of accessing the file contents is by going through the data_blocks[] table and the File extension blocks. An empty file consists of just a File header block, with 'byte_size' equal to 0, and no Data block pointers in 'data_blocks[]'. * File extension block (BSIZE bytes) (first pointer in File header) ------------------------------------------------------------------------------------------------ 0/ 0x00 ulong 1 type primary type : T_LIST (== 16) 4/ 0x04 ulong 1 header_key self pointer 8/ 0x08 ulong 1 high_seq number of data blk ptr stored 12/ 0x0c ulong 1 UNUSED unused (== 0) 16/ 0x10 ulong 1 UNUSED unused (== 0) 20/ 0x14 ulong 1 chksum rootblock algorithm 24/ 0x18 ulong * data_blocks[] data blk ptr (first at BSIZE-204) * = (BSIZE/4) - 56 BSIZE-200/-0xc8 ulong 46 info unused (== 0) BSIZE- 16/-0x10 ulong 1 UNUSED unused (== 0) BSIZE- 12/-0x0c ulong 1 parent file header block BSIZE- 8/-0x08 ulong 1 extension next file header extension block, 0 for the last BSIZE- 4/-0x04 ulong 1 sec_type secondary type : ST_FILE (== -3) ------------------------------------------------------------------------------------------------ * Data blocks (BSIZE bytes) (first pointer in File header 'first_data' and 'data_blocks[((BSIZE/4)-57)]') Old File System data block (BSIZE bytes) ------------------------------------------------------------------------------- 0/0 ulong 1 type primary type : T_DATA (== 8) 4/4 ulong 1 header_key pointer to file header block 8/8 ulong 1 seq_num file data block number (first is #1) 12/c ulong 1 data_size data size <= (BSIZE-24) 16/10 ulong 1 next_data next data block ptr (0 for last) 20/14 ulong 1 chksum rootblock algorithm 24/18 UCHAR * data[] file data size <= (BSIZE-24) ------------------------------------------------------------------------------- In OFS, there is a second way to read a file : using the Data block chained list. The list starts in File header ('first_data') and goes on with 'next_data' in each Data block. Fast File System (BSIZE bytes) ------------------------------------------------------------------------------- 0/0 UCHAR BSIZE data[] file data ------------------------------------------------------------------------------- In FFS, the only way to read or recover a file is to use data_blocks[] in the file header block and the File extension blocks. If a File header or File extension block is unreadable, there is no way to find the corresponding Data blocks. The OFS is more robust than FFS, but slower and can store less data on disk. As you see, disk salvaging is easier with OFS. When a file is deleted, only its File header block number is cleared from the Directory block (or from the same-hash-value list) and the bitmap is updated. File header block, Data blocks and File extension blocks are not cleared, but the bitmap blocks are updated. Nevertheless, the undelete operation is easy, as long as these blocks are not overwritten. ------------------------------------------------------------------------ 4.5 How are directories stored? Directory blocks are very similar to Rootblock, except they don't need information about the bitmap and disk, but they allow comments like files. * User directory block (BSIZE bytes) ------------------------------------------------------------------------------------------------ 0/ 0x00 ulong 1 type block primary type = T_HEADER (value 2) 4/ 0x04 ulong 1 header_key self pointer 8/ 0x08 ulong 3 UNUSED unused (== 0) 20/ 0x14 ulong 1 chksum normal checksum algorithm 24/ 0x18 ulong * ht[] hash table (entry block number) * = (BSIZE/4) - 56 for floppy disk: size= 72 longwords BSIZE-200/-0xc8 ulong 2 UNUSED unused (== 0) BSIZE-196/-0xc8 ushort 1 UID User ID BSIZE-194/-0xc8 ulong 1 GID Group ID BSIZE-192/-0xc0 ulong 1 protect protection flags (set to 0 by default) Bit If set, means If MultiUser FileSystem : Owner 0 delete forbidden (D) 1 not executable (E) 2 not writable (W) 3 not readable (R) 4 is archived (A) 5 pure (reetrant safe), can be made resident (P) 6 file is a script (Arexx or Shell) (S) 7 Hold bit. if H+P (and R+E) are set the file can be made resident on first load (OS 2.x and 3.0) 8 Group (D) : is delete protected 9 Group (E) : is executable 10 Group (W) : is writable 11 Group (R) : is readable 12 Other (D) : is delete protected 13 Other (E) : is executable 14 Other (W) : is writable 15 Other (R) : is readable 30-16 reserved 31 SUID, MultiUserFS Only BSIZE-188/-0xbc ulong 1 UNUSED unused (== 0) BSIZE-184/-0xb8 char 1 comm_len directory comment length BSIZE-183/-0xb7 char 79 comment[] comment (max. 79 chars permitted) BSIZE-104/-0x69 char 12 UNUSED set to 0 BSIZE- 92/-0x5c ulong 1 days last access date (days since 1 jan 78) BSIZE- 88/-0x58 ulong 1 mins last access time BSIZE- 84/-0x54 ulong 1 ticks in 1/50s of a seconds BSIZE- 80/-0x50 char 1 name_len directory name length BSIZE- 79/-0x4f char 30 dirname[] directory (max. 30 chars permitted) BSIZE- 49/-0x31 char 1 UNUSED set to 0 BSIZE- 48/-0x30 ulong 2 UNUSED set to 0 BSIZE- 40/-0x28 ulong 1 next_link FFS : hardlinks chained list (first=newest) BSIZE- 36/-0x24 ulong 5 UNUSED set to 0 BSIZE- 16/-0x10 ulong 1 hash_chain next entry ptr with same hash BSIZE- 12/-0x0c ulong 1 parent parent directory BSIZE- 8/-0x08 ulong 1 extension FFS : first directory cache block BSIZE- 4/-0x04 ulong 1 sec_type secondary type : ST_USERDIR (== 2) ------------------------------------------------------------------------------------------------ You can obtain a directory listing exactly like with the root directory. ------------------------------------------------------------------------ 4.6 How are links implemented in AmigaDOS ? With the FFS, links were introduced. Alas, Commodore blundered again: soft like where terribly broken, so they removed support for them in AmigaDOS 3.0. Hard links are seen as files, and hard links to directories are allowed, which opens the way to endless recursion... In short, the whole implmentation is a mess. However, some shells (like Csh 5.37) support them, so I'm supplying the structure. 4.6.1 Hard links * Hard link (BSIZE bytes) ------------------------------------------------------------------------------------------------ 0/ 0x00 ulong 1 type block primary type = T_HEADER (value 2) 4/ 0x04 ulong 1 header_key self pointer 8/ 0x08 ulong 3 UNUSED unused (== 0) 20/ 0x14 ulong 1 chksum normal checksum algorithm 24/ 0x18 ulong * UNUSED set to 0 * = (BSIZE/4) - 54 for floppy disk: size= 74 longwords BSIZE-192/-0xc0 ulong 1 protect protection flags (set to 0 by default) Bit If set, means If MultiUser FileSystem : Owner 0 delete forbidden (D) 1 not executable (E) 2 not writable (W) 3 not readable (R) 4 is archived (A) 5 pure (reetrant safe), can be made resident (P) 6 file is a script (Arexx or Shell) (S) 7 Hold bit. if H+P (and R+E) are set the file can be made resident on first load (OS 2.x and 3.0) 8 Group (D) : is delete protected 9 Group (E) : is executable 10 Group (W) : is writable 11 Group (R) : is readable 12 Other (D) : is delete protected 13 Other (E) : is executable 14 Other (W) : is writable 15 Other (R) : is readable 30-16 reserved 31 SUID, MultiUserFS Only BSIZE-188/-0xbc ulong 1 UNUSED unused (== 0) BSIZE-184/-0xb8 char 1 comm_len comment length BSIZE-183/-0xb7 char 79 comment[] comment (max. 79 chars permitted) BSIZE-104/-0x69 char 12 UNUSED set to 0 BSIZE- 92/-0x5c ulong 1 days last access date (days since 1 jan 78) BSIZE- 88/-0x58 ulong 1 mins last access time BSIZE- 84/-0x54 ulong 1 ticks in 1/50s of a seconds BSIZE- 80/-0x50 char 1 name_len hard link name length BSIZE- 79/-0x4f char 30 hlname[] hardlink name (max. 30 chars permitted) BSIZE- 49/-0x31 char 1 UNUSED set to 0 BSIZE- 48/-0x30 ulong 1 UNUSED set to 0 BSIZE- 44/-0x2c ulong 1 real_entry FFS : pointer to "real" file or directory BSIZE- 40/-0x28 ulong 1 next_link FFS : hardlinks chained list (first=newest) BSIZE- 36/-0x24 ulong 5 UNUSED set to 0 BSIZE- 16/-0x10 ulong 1 hash_chain next entry ptr with same hash BSIZE- 12/-0x0c ulong 1 parent parent directory BSIZE- 8/-0x08 ulong 1 UNUSED set to 0 BSIZE- 4/-0x04 ulong 1 sec_type secondary type : ST_LINKFILE = -4 ST_LINKDIR = 4 ------------------------------------------------------------------------------------------------ A 'real' entry is a file or directory entry, opposed to link entries. A hard link can only be created to the same disk as the real entry disk. Several links can be made on the same real entry. These are in just another linked list. 'real entry' always contains the real entry block pointer. 'next_link' stores the links linked list. New entries are added at the head: >ls ------rw-d 1912 15-May-96 22:28:08 real Chained list state : block# real next name ---------------------------- 484 0 0 real >ln real link1 >ls ------rw-d 1912 15-May-96 22:28:08 real -H----rw-d 1912 15-May-96 22:28:10 link1 -> Empty:real block# real next name ---------------------------- 484 0 104 real 104 484 0 link1 >ln link1 link2 >ls ------rw-d 1912 15-May-96 22:28:08 real -H----rw-d 1912 15-May-96 22:28:10 link1 -> Empty:real -H----rw-d 1912 15-May-96 22:28:12 link2 -> Empty:real block# real next name ---------------------------- 484 0 107 real 104 484 0 link1 107 484 104 link2 The links are stored 'newest first', due to the adding at head. real -> newest link -> ... -> oldest link -> 0 -> means "points to" 4.6.2 Soft links * Soft link (BSIZE bytes) ------------------------------------------------------------------------------------------------ 0/ 0x00 ulong 1 type block primary type = T_HEADER (value 2) 4/ 0x04 ulong 1 header_key self pointer 8/ 0x08 ulong 3 UNUSED unused (== 0) 20/ 0x14 ulong 1 chksum normal checksum algorithm 24/ 0x18 ulong * symbolic_name path name to referenced object, Cstring * = ((BSIZE - 224) - 1) for floppy disk: size= 288 - 1 chars BSIZE-200/-0xc8 ulong 2 UNUSED unused (== 0) BSIZE-192/-0xc0 ulong 1 protect protection flags (set to 0 by default) Bit If set, means If MultiUser FileSystem : Owner 0 delete forbidden (D) 1 not executable (E) 2 not writable (W) 3 not readable (R) 4 is archived (A) 5 pure (reetrant safe), can be made resident (P) 6 file is a script (Arexx or Shell) (S) 7 Hold bit. if H+P (and R+E) are set the file can be made resident on first load (OS 2.x and 3.0) 8 Group (D) : is delete protected 9 Group (E) : is executable 10 Group (W) : is writable 11 Group (R) : is readable 12 Other (D) : is delete protected 13 Other (E) : is executable 14 Other (W) : is writable 15 Other (R) : is readable 30-16 reserved 31 SUID, MultiUserFS Only BSIZE-188/-0xbc ulong 1 UNUSED unused (== 0) BSIZE-184/-0xb8 char 1 comm_len comment length BSIZE-183/-0xb7 char 79 comment[] comment (max. 79 chars permitted) BSIZE-104/-0x69 char 12 UNUSED set to 0 BSIZE- 92/-0x5c ulong 1 days last access date (days since 1 jan 78) BSIZE- 88/-0x58 ulong 1 mins last access time BSIZE- 84/-0x54 ulong 1 ticks in 1/50s of a seconds BSIZE- 80/-0x50 char 1 name_len soft link name length BSIZE- 79/-0x4f char 30 slname[] softlink name (max. 30 chars permitted) BSIZE- 49/-0x31 char 1 UNUSED set to 0 BSIZE- 48/-0x30 ulong 8 UNUSED set to 0 BSIZE- 16/-0x10 ulong 1 hash_chain next entry ptr with same hash BSIZE- 12/-0x0c ulong 1 parent parent directory BSIZE- 8/-0x08 ulong 1 UNUSED set to 0 BSIZE- 4/-0x04 ulong 1 sec_type secondary type : ST_SOFTLINK = 3 ------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------ 4.7 How are the blocks associated with the directory cache mode ? To speed up directory listing, Directory cache blocks have been created. Directory cache blocks are also organised in chained lists. The list starts at the directory block (root or normal directory) with the 'extension' field. * Directory cache block (BSIZE bytes) ------------------------------------------------------------------------------- 0/0 ulong 1 type DIRCACHE == 33 (0x21) 4/4 ulong 1 header_key self pointer 8/8 ulong 1 parent parent directory 12/c ulong 1 records_nb directory entry records in this block 16/10 ulong 1 next_dirc dir cache chained list 20/14 ulong 1 chksum normal checksum 24/18 UCHAR * records[] entries list (size = BSIZE-24) ------------------------------------------------------------------------------- The directory entries are stored this way : * Directory cache block entry record (26 <= size (in bytes) <= 77) ------------------------------------------------------------------------------- 0 ulong 1 header entry block pointer (the link block for a link) 4 ulong 1 size file size (0 for a directory or a link) 8 ulong 1 protect protection flags (0 for a link ?) (see file header or directory blocks) 12 ushort 1 UID user ID 14 ushort 1 GID group ID 16 short 1 days date (always filled) 18 short 1 mins time (always filled) 20 short 1 ticks 22 char 1 type secondary type 23 char 1 name_len 1 <= len <= 30 (nl) 24 char ? name name 24+nl char 1 comm_len 0 <= len <= 22 (cl) 25+nl char ? comment comment 25+nl+cl char 1 OPTIONAL padding byte(680x0 longs must be word aligned) ------------------------------------------------------------------------------- ------------------------------------------------------------------------ 5. How does a blank disk look like ? A minimal blank disk has a Bootblock, a Rootblock and a Bitmap block. 5.1 a Minimal blank floppy disk * The Bootblock (0 and 1) 0 char 4 ID 'D''O''S' + flags 4 long 1023 full of zeros * The Rootblock (880) 0 long 1 type 2 12/c long 1 ht_size 0x48 20/14 long 1 checksum computed 312/138 long 1 bm_flag -1 (valid bitmap) 316/13c long 1 bm_pages[0] bitmap sector # 420/1a4 long 1 last access date 424/1a8 long 1 last access time 428/1ac long 1 last access time 432/1b0 char 1 disk_name size 433/1b1 char ? disk_name 472/1d8 long 1 last access date 476/1dc long 1 last access time 480/1e0 long 1 last access time 484/1e4 long 1 creation date 488/1e8 long 1 creation time 492/1ec long 1 creation time 504/1f8 long 1 FFS : first dir cache sector or 0 508/1fc long 1 sub_type 1 Unspecified fields are set to 0. * The Bitmap block (here 881) for a DD disk 0 long 1 checksum 4 long 27 free sectors 0xffffffff 112/70 long 1 root+bitmap 0xffff3fff 116/74 long 27 free sectors 0xffffffff 120/78 long 72 unused !=0 ------------------------------------------------------------------------ 5.2 A 'Bootable' floppy disk * The Bootblock becomes : 0/0x00 long 1 ID 'D''O''S' + flags 4/0x04 long 1 checksum computed 8/0x08 long 1 rootblock ? 880 12/0x0c byte 81 bootcode AmigaDOS 3.0 version values disassembled --------------+--------------------- 43FA003E lea exp(pc),a1 ;Lib name 7025 moveq #37,d0 ;Lib version 4EAEFDD8 jsr -552(a6) ;OpenLibrary() 4A80 tst.l d0 ;error == 0 670C beq.b error1 2240 move.l d0,a1 ;lib pointer 08E90006 0022 bset #6,34(a1) ;(*) 4EAEFE62 jsr -414(a6) ;CloseLibrary() 43FA0018 error1: lea dos(PC),a1 ;name 4EAEFFA0 jsr -96(a6) ;FindResident() 4A80 tst.l d0 670A beq.b error2 ;not found 2040 move.l d0,a0 20680016 move.l 22(a0),a0 ;DosInit sub 7000 moveq #0,d0 4E75 rts 70FF error2: moveq #-1,d0 4E75 rts 646F732E 6C696272 617279 dos: "dos.library" 00 ;padding byte 65787061 6E73696F 6E2E6C69 62726172 79 exp: "expansion.library" 93/0x5d byte 931 full of zeros (*) from Thomas Kessler (tkessler@ra.abo.fi), may 1997 : This bit tells the shell (which opens its shell-window when booting the startup-sequence) not to open window unless needed, so a black screen stays there during boot instead of an empty shell-windows (it's a os2.x feature). ------------------------------------------------------------------------ 5.3 A Directory cache mode floppy disk * A directory cache block (here 882) 0 long 1 type 0x21 4 long 1 self pointer 882 8 long 1 cached dir 880 (root) 12/c long 1 entries number 0 16/10 long 1 next dir cache 0 (last) 20/14 long 1 checksum computed 24 long 122 full of zeros ------------------------------------------------------------------------ 5.4 International Mode The toupper() function in the HashName() function (3.2.1 paragraph) is replaced by the following function with the aim of better handling international characters : int intl_toupper(int c) { return (c>='a' && c<='z') || (c>=224 && c<=254 && c!=247) ? c - ('a'-'A') : c ; } In the Amiga ASCII table, the international character codes are between 192 and 254. Uppercase caracters are between 192 and 222, the lowercase versions of them are between 224 and 254. The only exception are the codes 215 and 247, which are respectively the multiply sign and the divide sign. The Amiga character set is the same as ISO 8859 Latin-1 character set, often assumed in HTML pages. This character set is described here : http://www.w3c.org/ ------------------------------------------------------------------------ 6. The structure of a hard disk The following structures are mainly extracted from the 'devices/hardblocks.h' and 'dos/filehandler.h' files delivered in Commodore developer kits. The hard disk specific structures mainly store the drive geometry, the written partitions sizes and the filesystem bootcode. The five kind of blocks are in a reserved area, at the beginning of the surface. The first of them, Rigid Disk block (RDSK), must be found within the first 16 blocks of BSIZE lenght. But it can be written inside the data area, which is dangerous. 6.1 What is the Rigid Disk Block ? * Rigid Disk block (256 bytes) must exist within the first 16 blocks ------------------------------------------------------------------------------- 0/0 char 4 id 'RDSK' 4/4 ulong 1 size in longs == 64 8/8 long 1 checksum classic Rootblock algorithm 12/c ulong 1 hostID SCSI Target ID of host (== 7 for IDE and ZIP disks) 16/10 ulong 1 block size typically 512 bytes, but can be other powers of 2 20/14 ulong 1 flags typically 0x17 Bit If set means : 0 No disks exists to be configured after this one on this controller 1 No LUNs exists to be configured greater than this one at this SCSI Target ID 2 No target IDs exists to be configured greater than this one on this SCSI bus 3 Don't bother trying to perform reselection when talking to this drive 4 Disk indentification valid 5 Controller indentification valid 6 Drive supports SCSI synchronous mode (can be dangerous if it doesn't) 24/18 ulong 1 Bad blockList block pointer (-1 means last block) 28/1c ulong 1 PartitionList block pointer (-1 means last) 32/20 ulong 1 FileSysHdrList block pointer (-1 means last) 36/24 ulong 1 DriveInit code optional drive-specific init code DriveInit(lun,rdb,ior) : "C" stack and d0/a0/a1 40/28 ulong 6 RESERVED == -1 Physical drive caracteristics 64/40 ulong 1 cylinders number of drive cylinder 68/44 ulong 1 sectors sectors per track 72/48 ulong 1 heads number of drive heads 76/4c ulong 1 interleave 80/50 ulong 1 parking zone landing zone cylinders soon after the last cylinder 84/54 ulong 3 RESERVED == 0 96/60 ulong 1 WritePreComp starting cyl : write precompensation 100/64 ulong 1 ReducedWrite starting cyl : reduced write current 104/68 ulong 1 StepRate drive step rate 108/6c ulong 5 RESERVED == 0 Logical drive caracteristics 128/80 ulong 1 RDB_BlockLo low block of range reserved for hardblk 132/84 ulong 1 RDB_BlockHi high block of range for this hardblocks 136/88 ulong 1 LoCylinder low cylinder of partitionable disk area 140/8c ulong 1 HiCylinder high cylinder of partitionable data area 144/90 ulong 1 CylBlocks number of blocks available per cylinder 148/94 ulong 1 AutoParkSeconds zero for no autopark 152/98 ulong 1 HighRSDKBlock highest block used by RDSK (not including replacement bad blocks) 156/9c ulong 1 RESERVED == 0 Drive identification 160/a0 char 8 DiskVendor ie 'IOMEGA' 168/a8 char 16 DiskProduct ie 'ZIP 100' 184/b8 char 4 DiskRevision ie 'R.41' 188/bc char 8 ControllerVendor 196/c4 char 16 ControllerProduct 212/d4 char 4 ControllerRevision 216/d8 ulong 10 RESERVED == 0 256/100 ------------------------------------------------------------------------------- * How to find the physical geometry of the disk ? A hard disk is made of several physical disks. They have one head for each writable side. Each physical disk consists of several tracks, which consist of several sectors. One cylinder is the set of the tracks which have the same number on each disk. The total size of the hard disk is expressed in cylinders ('cylinders'). The size of a cylinder is : the number of heads per cylinder ('heads') x the number of sectors per track ('sectors') x the size of a block ('block size'). The 'CylBlocks' field equals to 'heads' x 'sectors'. The reserved area is often the 2 first cylinders, between the 'RDB_BlockLo' block and the 'RDB_BlockHi' block, included. The partitionable area, starts at the 'LoCylinder' cylinder until the 'HiCylinder' cylinder, included. The really last used sector in the reserved area is the sector numbered 'HighRSDKBlock', the first is numbered 0. The SCSI 'hostID' is set to the id of the SCSI host controller, which is typically 7. Real SCSI drives ID must be between 0 and 6. The RDSK block is the "root" of the reserved area. It also contains the first blocks of three linked lists : one the bad blocks replacement, one for the partition definitions and one last for the filesystem information. Some geometry examples : * a Zip disk : 2891 cylinders, 1 head, 68 sectors, * my 80Mb Seagate IDE harddisk : 980 cylinders, 10 heads, 17 sectors. * a 500 Mbyte Fujitsu 2624SA: 1472 cylinders, 11 heads, 63 sectors * a 50 Mbyte Quantum LPS52: 2085 cylinders, 1 head, 49 sectors ------------------------------------------------------------------------ 6.2 How are bad blocks managed ? * Bad Block block (BSIZE bytes) first in RDSK 'BadBlockList' field ------------------------------------------------------------------------------- 0/0 ulong 1 id 'BADB' 4/4 ulong 1 size in longs == 128 for BSIZE = 512 8/8 long 1 checksum 12/c ulong 1 HostID == 7 ? 16/10 ulong 1 next next BadBlock block 20/14 ulong 1 RESERVED 24/18 * BlockPairs[] bad block entries table * size = ((BSIZE/4)-6)/2 (for BSIZE=512 = 61*8 byte entries) ------------------------------------------------------------------------------- * Bad Block entry (8 bytes) stored in BadBlock 'BlockPairs[]' field ------------------------------------------------------------------------------- 0/0 ulong 1 BadBlock block number of bad block 4/4 ulong 1 GoodBlock block number of replacement block ------------------------------------------------------------------------------- ------------------------------------------------------------------------ 6.3 How are partitions stored? * Partition block (256 bytes) first in RDSK 'PartitionList' field ------------------------------------------------------------------------------- 0/0 char 4 ID 'PART' 4/4 ulong 1 size in long of checksummed structure (== 64) 8/8 ulong 1 checksum classic algorithm 12/c ulong 1 hostID SCSI Target ID of host (== 7) 16/10 ulong 1 next block number of the next Partitionblock 20/14 ulong 1 Flags Bit If set means 0 This partition is bootable 1 No automount 24/18 ulong 2 RESERVED 32/20 ulong 1 DevFlags preferred flags for OpenDevice 36/24 char 1 DriveName len length of Drive name (e.g. 3) 37/25 char 31 DriveName e.g. 'DH0' 68/44 ulong 15 RESERVED DOS Environment vector (DOSEnvVec) (often defined in MountLists) 128/80 ulong 1 size of vector == 16 (longs), 11 is the minimal value 132/84 ulong 1 SizeBlock size of the blocks in longs == 128 for BSIZE = 512 136/88 ulong 1 SecOrg == 0 140/8c ulong 1 Surfaces number of heads (surfaces) of drive 144/90 ulong 1 sectors/block sectors per block == 1 148/94 ulong 1 blocks/track blocks per track 152/98 ulong 1 Reserved DOS reserved blocks at start of partition usually = 2 (minimum 1) 156/9c ulong 1 PreAlloc DOS reserved blocks at end of partition (no impact on Root block allocation) normally set to == 0 160/a0 ulong 1 Interleave == 0 164/a4 ulong 1 LowCyl first cylinder of a partition (inclusive) 168/a8 ulong 1 HighCyl last cylinder of a partition (inclusive) 172/ac ulong 1 NumBuffer often 30 (used for buffering) 176/b0 ulong 1 BufMemType type of mem to allocate for buffers ==0 180/b4 ulong 1 MaxTransfer max number of type to transfer at a type often 0x7fff ffff 184/b8 ulong 1 Mask Address mask to block out certain memory often 0xffff fffe 188/bc ulong 1 BootPri boot priority for autoboot 192/c0 char 4 DosType 'DOS' and the FFS/OFS flag only also 'UNI'\0 = AT&T SysV filesystem 'UNI'\1 = UNIX boot filesystem 'UNI'\2 = BSD filesystem for SysV 'resv' = reserved (swap space) 196/c4 ulong 1 Baud Define default baud rate for Commodore's SER and AUX handlers, originally used with the A2232 multiserial board 200/c8 ulong 1 Control used by Commodore's AUX handler 204/cc ulong 1 Bootblocks Kickstart 2.0: number of blocks containing boot code to be loaded at startup 208/d0 ulong 12 RESERVED ------------------------------------------------------------------------------- There exists one 'PART' block per partition. The block pointers in the reserved area are relative to the beginning of the media. The block pointers in a partition are relative to the first block of the partition. The Rootblock of a partition is normally located in the middle of an AmigaDOS filesystem. Please see 4.2 What is a Rootblock? <#p42> for the exact calculation of it's location. The first two blocks of a partition contain a Bootblock. You have to use it to determine the correct file system, and if the international or dircache modes are used. Don't rely only on the PART and FSHD 'DosType' field. ------------------------------------------------------------------------ 6.4 What are FSHD blocks ? * Filesystem header block (256 bytes) first in RSDK 'FileSysHeaderList' ------------------------------------------------------------------------------- 0/0 char 4 id 'FSHD' 4/4 ulong 1 size in longs == 64 8/8 long 1 checksum classic algorithm 12/c ulong 1 hostID SCSI Target ID of host (often 7) 16/10 ulong 1 next block number of next FileSysHeaderBlock 20/14 ulong 1 flags 24/18 ulong 2 RESERVED 32/20 char 4 DosType 'DOS' and OFS/FFS DIRCACHE INTL bits 36/24 ulong 1 Version filesystem version 0x0027001b == 39.27 40/28 ulong 1 PatchFlags bits set for those of the following that need to be substituted into a standard device node for this filesystem : e.g. 0x180 to substitute SegList and GlobalVec Device node 44/2c ulong 1 Type device node type == 0 48/30 ulong 1 Task standard DOS "task" field == 0 52/34 ulong 1 Lock not used == 0 56/38 ulong 1 Handler filename to loadseg == 0 60/3c ulong 1 StackSize stacksize to use when starting task ==0 64/40 ulong 1 Priority task priority when starting task == 0 68/44 ulong 1 Startup startup msg == 0 72/48 ulong 1 SegListBlock first of linked list of LoadSegBlocks : note that this entry requires some processing before substitution 76/4c ulong 1 GlobalVec BCPL global vector when starting task =-1 80/50 ulong 23 RESERVED by PatchFlags 172/ac ulong 21 RESERVED ------------------------------------------------------------------------------- This block contains information on how to lauch the task which will manage the filesystem. You don't need it to reach partitions. ------------------------------------------------------------------------ 6.5 What are LSEG blocks ? * LoadSeg block (BSIZE bytes) first in FileSysHeaderBlock 'SegListBlocks' field ------------------------------------------------------------------------------- 0/0 char 4 id 'LSEG' 4/4 long * size in longs size of this checksummed structure * size = BSIZE/4 8/8 long 1 checksum classic checksum 12/c long 1 hostID SCSI Target ID of host (often 7) 16/10 long 1 next block number of the next LoadSegBlock (-1 for the last) 20/14 uchar * LoadData[] code stored like an executable, with relocation hunks * size = ((BSIZE/4) - 5) ------------------------------------------------------------------------------- This block contains the code of the filesystem. It isn't needed to reach partitions. ------------------------------------------------------------------------ 7. The Hard file : a big floppy dump file A hardfile is a file which contains an Amiga volume. It is created with WinUAE (http://www.winuae.net/), and not the Amiga and the AmigaDOS. WinUAE is able to produce an empty file with random contents of a choosen size, often several megabytes long. Under WinUAE, a AmigaDOS device appears, associated with the uaehf.device (UAE hardfile). You have to format it with the Workbench, and you obtain an 'hardfile'. This volume is then usable inside the emulator by AmigaDOS (it should also be mountable under Linux with the AFFS filesystem). For example a 8Mb hardfile could be mounted on a kickstart 1.3 Amiga with the following mountlist (from uae docs/README) : UAE0: Device = uaehf.device Unit = 0 Flags = 0 Surfaces = 1 BlocksPerTrack = 32 Reserved = 1 Interleave = 0 LowCyl = 0 ; HighCyl = 511 Buffers = 5 DosType = 0x444F5300 BufMemType = 1 An hardfile is like a floppy disk dump, but bigger : it has a bootblock, a rootblock, a bitmap and perhaps dircache blocks. The first three bytes of a hardfile is then 'D' 'O' 'S'. The geometry is : heads = 1, sectors = 32, 'cylinders' depends the hardfile size. ------------------------------------------------------------------------ 8. Advanced information Bitmap related * Bitmap allocation starts at root block, upto highest block. The next allocated blocks are located just after boot blocks and finally the last allocated block is the sector before root block. root -> max -> boot+1 -> root-1 -> means "followed on disk by" If you free some blocks by deleting a file, for example, the first next used block will be the first free block encountered starting from the Rootblock. The just freed blocks will be reused. It means that when you delete a file and you want to recover it, don't write anything else to the disk. This strategy must have been chosen to minimize fragmentation. Files related * The order in which data and file extension blocks for a given file are written on disk differs with OFS and FFS. * OFS & FFS : All the data blocks of the file header block are written first. * FFS : Then follow all the file extension blocks of the file, then all the remaining data blocks are written. OFS : Each file extension block is followed by the related data blocks. So the last extension block is followed by the remaining data blocks. OFS: header -> data blocks -> ext. block -> data blocks -> ext. block -> data blocks FFS: header -> data blocks -> all ext. block -> all remaining data blocks -> means "followed on disk by" This difference is probably the main reason why FFS is faster then OFS. Under FFS, the hash chains are sorted by block number. Comparison chart of the ADF logical blocks root dir fileh hlink slink fext data dirc ---------------------------------------------------------------------------------------- 0/ 0x00 1st_type 2 2 2 2 2 16 8 33 4/ 0x04 header_key / x x x x x x x 8/ 0x08 / / nb_blo / / nb_blo block# PARENT 12/ 0x0c table_size 72 / / / / / nb_data nb_rec 16/ 0x10 list / / data#1 / / / next next 20/ 0x14 chksum x x x x x x x x 24/ 0x18 table ht ht blocks / / blocks data records ... BSIZE-184/-0xb8 comment_len / x x / / / / / BSIZE-183/-0xb7 comment / x x / / / / / ... BSIZE- 92/-0x5c days x x x x x / / / BSIZE- 88/-0x58 mins x x x x x / / / BSIZE- 84/-0x54 ticks x x x x x / / / BSIZE- 80/-0x50 name_len x x x x x / / / BSIZE- 79/-0x4f name x x x x x / / / ... BSIZE- 16/-0x10 hash_chain / x x / / / BSIZE- 12/-0x0c parent / x x x x fhdr / / BSIZE- 8/-0x08 extension cache cache fext / / next / / BSIZE- 4/-0x04 2nd_type 1 2 -3 -4/4 3 -3 / / ---------------------------------------------------------------------------------------- type of blocks : root=rootblock, dir=directory, fileh=file header, fext=file extension, hlink=hard link, slink=soft link, dirc=directory cache, data=OFS data. special values : /=unused x=used next=next block of same type How to rename an entry ? 1. Compute the new hashvalue 2. Move the first sector pointer from the old hashvalue index to the new one 3. Change the name in the directory or file header block ------------------------------------------------------------------------ 9. References and links * ASM Sources: * Scoopex and Crionics disassembled demo hardloaders * 'the floppy disk book' copier source file, DATA BECKER books, 1988 * On-Line material : * Very good 'ded.doc' file including Hard Disk information : ftp://ftp.funet.fi/pub/amiga/utilities/disk/Ded-1.11.lha * A clean track-loader which doesn't use AmigaDOS (by Patrik Lundquist) : ftp://ftp.wustl.edu/pub/aminet/dev/asm/t-loader.lha * A replacement for 'trackdisk.device' : ftp://ftp.wustl.edu/pub/aminet/disk/misc/hackdisk202.lha * 'amigadisk_hardware.doc' (by Dave Edwards, Mark Meany, ... of ACC) : http://home.sol.no/svjohan/assem/refs/diskHW.lha * DiskMonTools, a very good MFM/filesystem disk monitor for the Amiga : ftp://uk.aminet.net/pub/aminet/disk/moni/DiskMonTools.lha * Books : * The Amiga Guru Book, Chapter 15, Ralph Babel, 1993 * Rom Kernel Reference Manual : Hardware, pages 235-244, Addison Wesley * Rom Kernel Reference Manual : Libraries and Devices, Appendix C, Addison Wesley * La Bible de l'Amiga, Dittrich/Gelfand/Schemmel, Data Becker, 1988. The AmigaDOS reference manual probably contains a lot of information about Amiga file systems, but i don't own it (Addison Wesley). The most detailed information about AmigaDOS can be found in Ralph Babel's "Amiga Guru Book". ------------------------------------------------------------------------ 10. C routines : the ADF library The ADFlib is a portable C library designed to manage Amiga formatted devices like harddisks and ZIP disks, or dump files of this kind of media via the .ADF format. The API permits you to : * mount/unmount a device (real one or a dump file), * mount/unmount a volume (partition), * create/open/close/delete/move/undelete a file, * read/write bytes from/to a file, * create/delete/undelete a directory, * get directory contents, change current directory, get parent directory. A callback system makes it easy to write a real device driver for any platform. The *ADFOpus* ( http://adfopus.sourceforge.net/) application (a useful Windows Explorer like for ADF files and devices), written by Dan Sutherlan is able to access from NT4 an 2.5 inches harddisk formatted under AmigaDOS. The *ADFView* Windows Explorer shell extension (http://www.viksoe.dk/code/adfview.htm) written by Bjarke Viksoe is also using ADFlib. Hard-disks under W2000 are also supported. See the 1.2 section <#p12> to see how to obtain the package. ------------------------------------------------------------------------ 11. Other Amiga FileSystems * An Amiga filesystem for Linux 0.99pl2 by Ray Burr (read only, hard disk): ftp://tsx-11.mit.edu/pub/linux/patches/amigaffs.tar.Z * The AFFS filesystem inside the Linux kernel distribution by Hans-Joachim "JBHR" Widmaier (RDSK, links and international mode supported, dircache disks read-only): ftp://ftp.us.kernel.org in /usr/src/linux/fs/affs/ Currently maintained by Roman Zippel (zippel@linux-m68k.org) * An .ADF manipulation package for DOS/Windows, "ADF-suite" (GUI, Shareware, no sources included): link broken ------------------------------------------------------------------------ The .ADF format FAQ ends here ! unadf-0.7.11a/Faq/adf_info.html0000644000000000000000000024447210554753534014726 0ustar rootroot The .ADF (Amiga Disk File) format FAQ

The .ADF (Amiga Disk File) format FAQ

Laurent Clévy, lclevy@club-internet.fr

v1.11 - March 5th, 2005

This document describes the .ADF file format. An Amiga Disk File is a sector per sector dump of an Amiga formatted disk. The intent is to explain in detail how the Amiga stores files and directories on floppy and hard disks.
A set of C routines (ADFlib) will be supplied to manage the ADF format.

0. Changes

1. Introduction

2. How bytes are physically read from and written to a disk ?

3. What is the Amiga floppy disk geometry ?

4. What is the logical organisation of an Amiga volume ?

5. How does a blank disk look like ?

6. The structure of a hard disks ?

7. The Hard file : a big floppy dump file

8. Advanced information

9. References and links

10. C Routines : the ADF Library

11. Other Amiga file systems


0. Changes

Since 1.10 (November 27th, 2001)
  • Links updated
  • Amiga Floppy Reader link removed. The project seems cancelled.
Since 1.09 (3. Sep 1999)
  • [add] ADFlib is used by ADFview from Bjarke Viksoe
  • [chg] URLs fixes
Since 1.08 (2. August 1999)
  • [chg] fix: the hashvalue function was buggy on some rare name
  • [chg/add] suggestions (last ones) by Hans-Joachim.
Since version 1.07 (27. May 1999)
  • [chg] suggestions by Jörg Strohmayer (author of aminet:disk/moni/DiskMonTools.lha)
  • [chg] suggestions by Hans-Joachim Widmaier
  • [chg] minor additions to the MFM track format, from an online version of "RKRM : Libraries and Devices, appendix C"
Since version 1.06 (2. May 1999), by Heiko Rath (hr@brewhr.swb.de) :
  • [chg] Minor spelling corrections
  • [chg] Blocksizes other than 512 bytes documented
  • [chg] DosEnvVector extended
  • [add] link to the Amiga Floppy Reader project
Since version 1.04 (16. January 1999) :
  • [chg] Corrections suggested by Hans-Joachim Widmaier (Linux affs maintainer)
  • [add] The WinUAE hardfile format section is starting
Since version 0.9 (28. May 1997) :
  • [add] HTML version with figures
  • [add] Hard disk section added
  • [chg] Correction about DIRC and INTL modes (section 4.1)
  • [add] The whole rewritten ADF library is released (0.7.8) and used within the ADFOpus project (New site Gary Harris, Old site Dan Sutherland)
  • [chg] The bitmap checksum algorithm is the same as the rootblock algorithm
  • [add] Allowed/forbidden characters in volume and file names, 4GB limit
  • [add] how to rename an entry

1. Introduction

In this document, we will describe how the AmigaDOS is (was?) managing storage media, from the magnetic layer to the files and directories layer.

With physical layer, I'm talking about the way bytes are physically stored on a magnetic surface, with the RLL or MFM encoding.
The next layer, according to the 'most physical' to 'most conceptual' order, is the partitions layer : this is how the AmigaDOS is managing media with more then one partition, like Zip disks or hard disks.
The next and last layer is the volume layer : where the files and directories are stored.

The physical layer is described in the 2nd chapter,
The volume layer is the biggest part of the document (4th and 5th chapters), since it's the most interesting,
The partitions layer is explained in the 6th chapter.

Let's continue with more conventional things in an introduction.


1.1 Disclaimer and copyright

This document is Copyright (C) 1997-1999 by Laurent Clévy, but may be freely distributed, provided the author name and addresses are included and no money is charged for this document.

This document is provided "as is". No warranties are made as to its correctness.

Amiga and AmigaDOS are registered Trademarks of Gateway 2000.
Macintosh is a registered Trademark of Apple.


1.2 Feedback, updates

If you find any mistakes in this document, have any comments about its content, feel free to send me an e-mail.
Corrections are very welcome.

You can find new versions of this document at :


1.3 Conventions

In this document, hexadecimal values use the C syntax : for example 0x0c is the decimal value 12.

Byte ordering

Since the Amiga is a 680x0 based computer, integers that require more than one byte are stored on disk in 'Motorola order' : the most significant byte comes first, then the less significant bytes in descending order of significance (MSB LSB for two-byte integers, B3 B2 B1 B0 for four-byte integers). This is usually called big endian byte ordering.
The Intel based PCs are using the little endian byte ordering.

Vocabulary

A 'word' or 'short' is a 2-byte (16 bits) integer, a 'long' a 4-byte (32 bits) integer. Values are unsigned unless otherwise noted.

A 'block' in this document will be 512 consecutive bytes on disk, unless noted otherwise, the variable 'BSIZE' will denote the blocksize.
The word 'sector' and 'block' will be used as synonyms here, even if 'sector' is usually related to the physical side, and the 'block' to the logical side. This is because the AmigaDOS can only handle one sector per block. Some other Unix filesystems can have more then one sector per block.

A block pointer is the number of this block on the disk. The first one is the #0 block.
There are 'logical' and 'physical' block pointers. 'Logical' ones are related to the start of one volume, 'physical' one are related to the start of a physical media. If a volume starts at the #0 physical sector, a physical pointer and a logical pointer is the same thing, like with floppies.

A simple definition of 'Hashing' could be : "a method to access tables : given a number or a string, a hash function returns an index into an array". This definition is correct for this document, but there is a lot of other hashing methods, that might be far more complex.

Linked lists are cell-oriented data structures. Each cell contains a pointer to the next or previous cell or both, the last cell pointer is null.

C example :

struct lcell {
	char name[10];
	/* contains next cell adress, or NULL if this cell is the last */
	struct lcell *next_cell;
	};

Block names begin with a capital (Rootblock). Field names are noted between quotes ('field_name').

All formats are described as tables, one row per field. Here is an example with the beginning of the well known GIF format :

offset  type   length  name          comments
----------------------------------------------------------
0       char    3      signature     'GIF'
3       char    3      version       '87a' or '89a'
6       short   1      screen width  (little endian)
8       short   1      screen height (little endian)

The .ADF format is the format created and used by the -incredible- UNIX Amiga Emulator (UAE), written by Berndt Schmitt. The home page is here : http://www.freiburg.linux.de/~uae/

The .ADF files can be created with the program transdisk.


1.4 Acknowledgements

I would to thank here again the people who take time to send me corrections, suggestions and opinions about this document :
  • Hans-Joachim Widmaier for the -very detailed- review and suggestions,
  • Dan Sutherland (dan@chromerhino.demon.co.uk) for the suggestions and ideas,
  • Jorg Strohmayer (see Aminet:disk/moni/DiskMonTools.lha, his DiskMonTools utility)
  • Heiko Rath (hr@brewhr.swb.de) for some modifications.
  • Jean Yves Peterschmitt (jypeter@lmce.saclay.cea.fr) for the review,
  • Thomas Kessler (tkessler@ra.abo.fi) for the bootcode flag note.

2. How are bytes physically read from / written to a disk ?

The following part deals with the way the Amiga disk controller accesses the magnetic medium. If you only want to understand the .ADF format, you don't need to read this part.

Information is written on disk with magnetic fields. Magnetic fields can be made 'on' or 'off'. But the read/write heads are not capable of detecting directly if a field is on or off. An encoding is used to store memory bits on the medium. The CHANGE of fields polarisation will indicate if the bit is 1 or 0. For Amiga floppy disks (and PC floppies), the encoding scheme is MFM (Modified frequency modulation).

Notes on the Amiga floppy disk controller :

The Amiga floppy disk controller (FDC) which is called 'Paula' is very flexible. It is capable of reading/writting Amiga/PC/Macintosh/AppleII/C64 3.5 inches and 5.25 inches floppy disks.

Paula can read a variable number of bytes from disk, the PC FDC can't. The PC FDC uses the index hole to find the beginning of a track, Paula uses a synchronization word. The Macintosh uses GCR encoding instead of MFM.
In fact, Paula is simpler than the PC FDC because it does not perform automatically the decoding just after the read operation, and the encoding just before the write operation : it must be done by software. The MFM decoding/encoding is done by hardware with the PC FDC, the Amiga can do GCR or MFM decoding/encoding because it's done with the CPU. In some versions of the AmigaDOS, the decoding/encoding is made by the Blitter custom chip.

Classic PC FDCs can't read Amiga floppy disks even if they are MFM encoded on a 3.5 inch floppy, because they can not find the beginning of a track. This is why the .ADF format has been created.

However, a custom FDC available on PC machines is capable of reading/writing Amiga, PC, Macintosh, Atari and C64 floppies !!! This is CatWeasel : link

Paula parametrization for Amiga disks :

  • MFM encoding
  • Precompensation time : 0 nanoseconds
  • Controller clock rate : 2 microseconds per bit cell
  • Synchronization value : 0x4489

Paula is able to put the read/write heads on a cylinder, and is able to read with the lower or upper side head. A track of 0x1900 words is usually read.


2.1 What is MFM encoding/decoding ?

The MFM decoding is made by the Amiga CPU, not by Paula. This allows custom encoding, to protect floppies against copying for example.

Here follows the MFM encoding scheme :

    user's data bit      MFM coded bits
    ---------------      --------------
        1                   01
        0                   10 if following a 0 data bit
        0                   00 if following a 1 data bit

User data long words are split in two parts, a part with even bits part first, followed by a part with odd bits. Once encoded, the amount of data stored doubles.
The MFM decoding will transform magnetic fields into computer usuable bits.

The encoding process will take one long (user's data), and produces two longs (MFM coded longs): one for the even bits of the user long, a second for the odd bits of the user long.
Vice versa, the decoding process will take the half of two MFM longs to produce one user's long.


2.2 What is the MFM track format ?

Paula will search two synchronization words, and then read 0x1900 words of data. We will call those 0x1900 words a 'MFM track'.
There are 80 cylinders on a Amiga floppy disk. Each cylinder has 2 MFM tracks, 1 on each side of the disk.

Double density (DD) disks have 11 sectors per MFM track, High density (HD) disks have 22 sectors.

So a MFM track consists of 11/22 MFM encoded sectors, plus inter-track-gap. Note that sectors are not written from #0 to #10/21, you must use the 'info' field to restore the correct order when you read the tracks. Each MFM track begins with the first sector, and ends with the end of the last sector.
Each sector starts with 2 synchronization words. The synchronization value is 0x4489.


2.3 What is the MFM sector format ?

From RKRM: "Per-track Organization: Nulls written as a gap, then 11 or 22 sectors of data. No gaps written between sectors." There are brut data and encoded data.
Brut data (also called MFM data) doesn't need to be decoded, this is the synchronization data, the header checksum and data checksum.

The encoded parts are 'header' and 'data'.

Here it comes :

00/0x00	word	2	MFM value 0xAAAA AAAA (when decoded : two bytes of 00 data)

	SYNCHRONIZATION
04/0x04	word	1	MFM value 0x4489 (encoded version of the 0xA1 byte)
06/0x06	word	1	MFM value 0x4489

	HEADER
08/0x08	long	1	info (even bits)
12/0x0c	long	1	info (odd bits)
			decoded long is : 0xFF TT SS SG
				0xFF = Amiga v1.0 format
				TT = track number ( 3 means cylinder 1, head 1)
				SS = sector number ( 0 upto 10/21 )
					sectors are not ordered !!!
				SG = sectors until end of writing (including
					current one)

			Example for cylinder 0, head 1 of a DD disk :
				0xff010009
				0xff010108
				0xff010207
				0xff010306
				0xff010405
				0xff010504
				0xff010603
				0xff010702
				0xff010801
				0xff01090b
				0xff010a0a
                        the order of the track written was sector 9, sector 10,
                         sector 0, sector 1 ...

                        (see also the note below from RKRM)

            Sector Label Area : OS recovery info, reserved for future use

16/0x10	long	4	sector label (even)
32/0x20	long	4	sector label (odd)
                    decoded value is always 0

            This is operating system dependent data and relates to how AmigaDOS
            assigns sectors to files.

            Only available to 'trackdisk.device', but not with any other floppy
            or hard disk device.

	END OF HEADER

48/0x30	long	1	header checksum (even)
52/0x34	long	1	header checksum (odd)
			(computed on mfm longs,
			longs between offsets 8 and 44 
			== 2*(1+4) longs)

56/0x38	long	1	data checksum (even)
60/0x3c	long	1	data checksum (odd)
			(from 64 to 1088 == 2*512 longs)

	DATA
64/0x40	long	512	coded data (even)
576/0x240 long	512	coded data (odd)
1088/0x440
	END OF DATA

Note from RKRM :

The track number and sector number are constant for each particular
sector. However, the sector offset byte changes each time we rewrite
the track.

The Amiga does a full track read starting at a random position on the
track and going for slightly more than a full track read to assure
that all data gets into the buffer. The data buffer is examined to
determine where the first sector of data begins as compared to the
start of the buffer. The track data is block moved to the beginning
of the buffer so as to align some sector with the first location in
the buffer.

Because we start reading at a random spot, the read data may be
divided into three chunks: a series of sectors, the track gap, and
another series of sectors. The sector offset value tells the disk
software how many more sectors remain before the gap. From this the
software can figure out the buffer memory location of the last byte
of legal data in the buffer. It can then search past the gap for the
next sync byte and, having found it, can block move the rest of the
disk data so that all 11 sectors of data are contiguous.

    Example:

        The first-ever write of the track from a buffer looks
        like this:

         |sector0|sector1|sector2|......|sector10|

        sector offset values:

                  11      10      9     .....     1

        (If I find this one at the start of my read buffer, then I
         know there are this many more sectors with no intervening
         gaps before I hit a gap).  Here is a sample read of this
         track:

        |sector9|sector10||sector0|...|sector8|

        value of 'sectors till end of write':

                  2        1     ....    11   ...    3

        result of track re-aligning:

        |sector9|sector10|sector0|...|sector8|

        new sectors till end of write:

                 11       10      9    ...     1

        so that when the track is rewritten, the sector offsets
        are adjusted to match the way the data was written.

2.4 How to decode MFM data ?

C algorithm :


#define MASK 0x55555555	/* 01010101 ... 01010101 */
unsigned long *p1;	/* MFM coded data buffer (size == 2*data_size) */
unsigned long *q;	/* decoded data buffer (size == data_size) */
unsigned long a,b;
unsigned long chksum;
int data_size;		/* size in long, 1 for header's info, 4 for header's sector label */
int count;

chksum=0L;
/* the decoding is made here long by long : with data_size/4 iterations */
for (count=0; count<data_size/4; count++) {
	a = *p1;                /* longs with even bits */
	b = *(p1+data_size);    /* longs with odd bits : located 'data_size' bytes farther */
	chksum^=a;              /* eor */
	chksum^=b;
        /*
         * MFM decoding, explained on one byte here (x and y will produce t) :
         * the MFM bytes 'abcdefgh' == x and 'ijklmnop' == y will become
         * y & 0x55U = '0j0l0n0p'
         * ( x & 0x55U) << 1 = 'b0d0f0h0'
         * '0j0l0n0p' | 'b0d0f0h0' = 'bjdlfnhp' == t
         */ 
	/* on one long here : */
	*q = ( b & MASK ) | ( ( a & MASK ) << 1 );
	p1++;    /* next 'even bits' long and 'odd bits' long  */
	q++;     /* next location of the future decoded long */
	}
chksum&=MASK;	/* must be 0 after decoding */
For example, to decode the DATA field of a MFM sector :
  • data_size is equal to 512,
  • p1 points to 64 bytes after the beginning of the MFM sector,
  • q points to a 512 unsigned bytes array.

3. What is the Amiga floppy disk geometry ?

After MFM decoding, you have usuable 'sectors' or 'blocks' into memory.

Here we remind the disk geometries for Double Density disks (DD) and High Density disks (HD) :
		bytes/sector	sector/track	track/cyl	cyl/disk
------------------------------------------------------------------------
DD disks	512		11		2		80
HD disks 	512		22		2		80
The relations between sectors, sides and cylinders are for a DD disk :
Block	sector	side	cylinder
--------------------------------
0	0	0	0
1	1	0	0
2	2	0	0
...
10	10	0	0
11	0	1	0
...
21	10	1	0
22	0	0	1
..
1759	10	1	79
Order = increasing sectors, then increasing sides, then increasing cylinders.

A DD disk has 11*2*80=1760 (0 to 1759) blocks, a HD disk has 22*2*80=3520 blocks.

The length of .ADF files for a DD disk is therefore 512*11*2*80 = 901120 bytes.

Those 'raw' blocks, 512 consecutive bytes, store different 'logical' blocks to manage files and directories.

The classic Amiga filesystem has a internal command with one 32 bits wide offset parameter (unsigned). It tells where to start the read/write operation. The biggest size for an Amiga disk is therefore 2^32 = 4 GB.
Anyway, there exists a 3rd party patch which changes the 32 bits limit to 64 bits (on Aminet, disk/misc/ffstd64.lha).

Jorg Strohmayer added :
TD64 is an unofficial 3rd party hack. Official solution is NSD (new style device), updates for the internal devices and the filesystem are available from http://www.amiga.de. There is a patch for old (and TD64) devices too (NSDPatch).


4. What is the logical organisation of an Amiga volume ?

A volume is a floppy disk or a hard disk partition.

The first file system for the Amiga was embedded in the version 1.2 of AmigaDOS.
With version 2.xx of AmigaDOS the Fast File System (FFS) was introduced, an improved version of the 1.2, also called old file system (OFS).
The version 3.0 of AmigaDOS added an international characters mode (INTL) and a directory cache mode (DIRC).

Links are only supported under FFS.

The start of a floppy volume contains space for sectors which may contain boot code.
The middle of the volume contains information about the root (upper most) directory contents and information about free and used blocks.
Other blocks are of course used to store files and directories.

The file length, the directory tree depth, the number of entries per directory are only limited by disk size. (Actually the maximum filesize is limited to 4 Gbyte sizeof(ulong) which should normally be more than sufficient).

Let's introduce the logical structures used by the Amiga file system in a table (for floppies) :

Object		Related logical blocks
------------+----------------------------------------------------------------
Volume		Rootblock, Bitmap block
File		File Header block, Extension block, Data block, Link block
Directory	Rootblock, Directory block, Directory Cache block, Link block
The main data types are a trees and linked lists.


4.1 What is a Bootblock ?

Prior to Kickstart 2.0 the bootblock was hardcoded to consist of the first two sectors of the floppy disks (sector #0 and #1). As of Kick 2.0, booting via the boot-block could be done with any device driver and the number of blocks could be changed independantly of the number of reserved blocks by using BOOTBLOCKS in the DOS environment vector (DosEnvVec).
* BootBlock
-------------------------------------------------------------------------------
offset	size    number	name		meaning
-------------------------------------------------------------------------------
0/0x00  char    4       DiskType	'D''O''S' + flags
                                        flags = 3 least signifiant bits
                                               set         clr
					  0    FFS         OFS
                                          1    INTL ONLY   NO_INTL ONLY
                                          2    DIRC&INTL   NO_DIRC&INTL
4/0x04  ulong   1       Chksum          special block checksum
8/0x08  ulong   1       Rootblock       Value is 880 for DD and HD 
					 (yes, the 880 value is strange for HD)
12/0x0c char    *       Bootblock code  (see 5.2 'Bootable disk' for more info)
                                        The size for a floppy disk is 1012,
                                        for a harddisk it is
                                        (DosEnvVec->Bootblocks * BSIZE) - 12
-------------------------------------------------------------------------------
The DiskType flag informs of the disk format.
  • OFS = Old/Original File System, the first one. (AmigaDOS 1.2)
  • FFS = Fast File System (AmigaDOS 2.04)
  • INTL = International characters Mode (see section 5.4).
  • DIRC = stands for Directory Cache Mode. This mode speeds up directory listing, but uses more disk space (see section 4.7).
The Old filesystem may have the international and dircache mode enabled. If the international mode is enabled, the bit #1 is set. If the dircache is enabled, its flag is set (bit #2), and the international mode is also enabled, but the related flag (bit #1) will stay cleared. The correct values for flag are therefore : 0 (OFS), 1 (FFS), 2 (OFS/INTL), 3 (FFS/INTL), 4 (OFS/DIRC&INTL), 5 (FFS/DIRC&INTL).

There are few differences between the two file systems :

  • OFS Datablock stores BSIZE-24 bytes (i.e. normally 488 bytes at most frequently used BSIZE of 512 bytes), FFS stores BSIZE bytes.
  • FFS supports directory caching, links and international mode,
  • the FFS is faster than OFS.
If the Bootblock starts with the three characters 'PFS', another filesystem is used in place of AmigaDOS : the Professional File System.

If the checksum and the DiskType are correct, the system will execute the bootblock code, at boot time, of course :-).

The Bootblock code is optional, see 5.2 section.

The Bootblock checksum algorithm follows :

* in 68000 assembler :

	lea 	bootbuffer,a0
        move.l  a0,a1
        clr.l   4(a1)			;clear the checksum
        move.w  #(BOOTBLOCKSIZE/4)-1,d1	;for floppy disks = 1024
                                        ;for hd = (DosEnvVec->Bootblocks * BSIZE)
        moveq   #0,d0
lpchk:  add.l   (a0)+,d0		;accumulation
        bcc.s   jump                    ;if carry set, add 1 to checksum
        add.l   #1,d0
jump:   dbf     d1,lpchk		;next long word

        not.l   d0
        move.l  d0,4(a1)		;new checksum


* in C (version 1):

#include<limits.h>
#define Short(p) ((p)[0]<<8 | (p)[1])
#define Long(p) (Short(p)<<16 | Short(p+2))

unsigned long newsum,d;
unsigned char buf[BOOTBLOCKSIZE];	/* contains bootblock */ 
                                        /* for floppy disks = 1024, */
                                        /* for hard disks = (DosEnvVec->Bootblocks * BSIZE) */
int i;

memset(buf+4,0,4);			/* clear old checksum */
newsum=0L;
for(i=0; i<BOOTBLOCKSIZE/4; i++) {
	d=Long(buf+i*4);
	if ( (ULONG_MAX-newsum) < d )	/* overflow */
		newsum++; 
	newsum+=d; 
} 

newsum=~newsum;		/* not */



* version 2 (From Ralph Babel's 'Install2.c', sent by Hans-Joachim)


unsigned long checksum, precsum;

checksum = 0;
for(i=0; i<BOOTBLOCKSIZE/sizeof(unsigned long); i++) {
    precsum = checksum;
    if ( (checksum+=Long(buf+i*4)) < precsum)   /* better 68000 to C translation of 'bcc' */
        ++checksum;
}
checksum = ~checksum;



4.2 What is a Rootblock ?

The Rootblock is located at the physical middle of the media : block number 880 for DD disks, block 1760 for HDs. The exact calculation where it is stored is as follows:

numCyls = highCyl - lowCyl + 1

highKey = numCyls * numSurfaces * numBlocksPerTrack - 1

rootKey = INT (numReserved + highKey) / 2

The Rootblock contains information about the disk : its name, its formatting date, etc ...

It also contains information to access the files/directories/links located at the uppermost (root) directory.

* Root block (BSIZE bytes) sector 880 for a DD disk, 1760 for a HD disk
------------------------------------------------------------------------------------------------
        0/ 0x00	ulong	1	type		block primary type = T_HEADER (value 2)
        4/ 0x04	ulong	1	header_key	unused in rootblock (value 0)
		ulong 	1 	high_seq	unused (value 0)
       12/ 0x0c	ulong	1	ht_size		Hash table size in long (= BSIZE/4 - 56)
                	                        For floppy disk value 0x48
       16/ 0x10	ulong	1	first_data	unused (value 0)
       20/ 0x14	ulong	1	chksum		Rootblock checksum
       24/ 0x18	ulong	*	ht[]		hash table (entry block number)
        	                                * = (BSIZE/4) - 56
                	                        for floppy disk: size= 72 longwords
BSIZE-200/-0xc8	ulong	1	bm_flag		bitmap flag, -1 means VALID
BSIZE-196/-0xc4	ulong	25	bm_pages[]	bitmap blocks pointers (first one at bm_pages[0])
BSIZE- 96/-0x60	ulong	1	bm_ext		first bitmap extension block
						(Hard disks only)
BSIZE- 92/-0x5c	ulong 	1 	r_days		last root alteration date : days since 1 jan 78
BSIZE- 88/-0x58	ulong 	1 	r_mins 		minutes past midnight
BSIZE- 84/-0x54	ulong 	1 	r_ticks 	ticks (1/50 sec) past last minute
BSIZE- 80/-0x50	char	1	name_len	volume name length
BSIZE- 79/-0x4f	char	30	diskname[]	volume name
BSIZE- 49/-0x31	char	1	UNUSED		set to 0
BSIZE- 48/-0x30	ulong	2	UNUSED		set to 0
BSIZE- 40/-0x28	ulong	1	v_days		last disk alteration date : days since 1 jan 78
BSIZE- 36/-0x24	ulong	1	v_mins		minutes past midnight
BSIZE- 32/-0x20	ulong	1	v_ticks		ticks (1/50 sec) past last minute
BSIZE- 28/-0x1c	ulong	1	c_days		filesystem creation date
BSIZE- 24/-0x18	ulong	1	c_mins 		
BSIZE- 20/-0x14	ulong	1	c_ticks
		ulong	1	next_hash	unused (value = 0)
		ulong	1	parent_dir	unused (value = 0)
BSIZE-  8/-0x08	ulong	1	extension	FFS: first directory cache block,
						0 otherwise
BSIZE-  4/-0x04	ulong	1	sec_type	block secondary type = ST_ROOT 
						(value 1)
------------------------------------------------------------------------------------------------

The characters '/' and ':' are forbidden in file and volume names, but *!@#$%|^+&_()=\-[]{}';",<>.? and accented like âè are allowed.

The date fields in the root block (and other blocks) are structured in the form of DAYS, MINS and TICKS. The DAYS field contains the number of days since January 1. 1978. MINS is the number of minutes that have passed since midnight and TICKS are expressed in 1/50s of a second. A day value of zero is considered illegal by most programs.

The r_date / r_min / r_ticks fields are updated to the last recent change of the root directory of this volume.

The v_date / v_min / v_ticks fields are updated whenever any change was made to this volume, not just the root directory.

The c_date / c_min / c_ticks fields contain the date and time when this volume was initialized (i.e. formatted) and is not changed during its lifetime.

Some date constraints : 0 <= Mins < 60*24, 0 <= Ticks < 50*60

The Amiga filesystem does not have an inherent year 2000 problem. If you want to know more about Y2K and the Amiga, you might take a look at : http://www.amiga.com.

4.2.1 How to find the first sector of a directory entry ?

Given the name of a file/directory/link you first have to compute its hash value with this algorithm :

* The hash function :

#include<ctype.h>

int HashName(unsigned char *name)
{
unsigned long hash, l;				/* sizeof(int)>=2 */
int i;

l=hash=strlen(name);
for(i=0; i<l; i++) {
        hash=hash*13;
        hash=hash + toupper(name[i]);	/* not case sensitive */
        hash=hash & 0x7ff;
        }
hash=hash % ((BSIZE/4)-56);		/* 0 < hash < 71
                                         * in the case of 512 byte blocks */

return(hash);
}

// this code only works with non international mode disks
// see section 5.4

The toupper() function is the one thing that distinguishes international from non-international filesystems. There was a bug in old AmigaDOS versions for this function applied to international caracters (ASCII codes > 128). A specific toupper() function (see section 5.4) was then created available with the 'international mode'.

The hash value is then used to access HashTable ('ht' field in Rootblock/Directory block).

HashTable[ HashValue ] contains the number of the first block of your object (File header block, Directory block or Link block).

But different names can result in the same HashValue. If more then one name has the same HashValue, the other blocks (for files and directory only) are stored in a chained list. This linked list starts at the 'next_hash' field of the File header or Directory block.

For example : 'file_1a', 'file_24' and 'file_5u' have the same hash value.

Here follows the method to find the requested block :

HashValue = HashName( name );
name=uppercase(name);
nsector = Hashtable[ HashValue ];
if (nsector != 0) {
	sector=Load(nsector);		/* reads the 'nsector' sector */
        sector.name = uppercase(sector.name);
        /*
         *  follows the 'same HashValue' chained list if needed
         */
	while ( sector.name != name and sector.Next_hash != 0) {
		sector = Load(nsector);
       	        sector.name = uppercase(sector.name);
	}
	if (sector.name != name)
		puts("File/Dir not found");
}
else
	puts("File/Dir not found");


// this code only works with non international mode disks
// see section 5.4
Figure : HashTable and Directory content

Filenames characters can be lowercase and uppercase, but as shown in the Hash function, are not case sensitive.

If, for a new entry, the value at hashTable[hashvalue] is different than 0, the new sector pointer will be stored in the last entry of the same-hashvalue-linked-list. It is necessary to check if the entry name already exists in this directory. In one word, in the same-hashValue list, the addition is made at the tail, not the head.
Jorg tells the list is instead sorted by block number.

4.2.2 How to list all the directory entries ?

Look through the whole HashTable and follow the same 'HashValue' linked lists if they exist.

4.2.3 How to compute the checksum ?

#define Short(p) ((p)[0]<<8 | (p)[1])
#define Long(p) (Short(p)<<16 | Short(p+2))

unsigned long newsum;
unsigned char buf[BSIZE];	/* contains rootblock */
int i;

memset(buf+20,0,4);		/* clear old checksum */
newsum=0L;
for(i=0; i<(BSIZE/4); i++)
	newsum+=Long(buf+i*4);
newsum=-newsum;			/* negation */

This checksum algorithm works for most block types except for Bootblock.

The bitmap table ('bm_pages[]') stores one or several pointers to Bitmap blocks. The first pointer is at index 0.


4.3 How are the free and used block lists managed?

Bitmap blocks contain information about free and allocated blocks. One bit is used per block. If the bit is set, the block is free, a cleared bit means an allocated block.

Bootblock allocation (2 for floppy, for hard disks the value can be found at DOSEnvVec->Bootblocks) is not stored in bitmap. Bitmap consists of longs, each describing the status of 32 blocks, where bit 0 corresponds to the lowest block number.

* Bitmap block (BSIZE bytes), often at rootblock+1
-------------------------------------------------------------------------------
0/0x00	long	1		checksum	normal algorithm
4/0x04	long	(BSIZE/4)-1	map
-------------------------------------------------------------------------------

Here follows for a DD disk the relationship between bitmap and block number :

block #		long #	bit #
-------------------------------
2		0	0
3		0	1
4		0	2
...
33		0	31
34		1	0
35		1	1
...
880		27	14
881		27	15
...
1759		54	28
1760		54	29
This map is 1758 bits long (1760-2) and is stored on 54 full filled long and the first 30th bits of the 55th long.

* What is the 'bm_ext' field in Rootblock ?

If 25 bitmap blocks (which pointers are stored in the Rootblock) are not sufficient (for Hard Disks > ca. 50 Mbyte), the pointers to the further bitmap blocks are stored in so called bitmap extension blocks. The form a (surprise, surprise!) linked list, starting at the bm_ext field in the Rootblock.

* Bitmap extension block (BSIZE bytes) (Hard disk only)
-------------------------------------------------------------------------------
       0/0x00	ulong	(BSIZE/4)-1	bitmap block pointers
BSIZE- 4/0x04	ulong	1		next (0 for last)
-------------------------------------------------------------------------------
The Bitmap extension linked list start at Rootblock with the 'bm_ext'.


4.4 How are files stored ?

Files are comprised of a file header block, which contains information about the file (size, last access time, data block pointers, ...) and the data blocks, which contain the actual data. The file header block contains up to BSIZE/4-56 data block pointers (which amounts to 72 with the usual 512 byte blocks).

If a file is larger than that, file extension blocks will be allocated to hold the data block pointers.

File extension blocks are organised in a linked list, which starts in File header block ('extension' field).

Figure : Chained lists of the blocks which store files

* File header block (BSIZE bytes) 
------------------------------------------------------------------------------------------------
        0/ 0x00 ulong	1	type		block primary type T_HEADER (==2)
        4/ 0x04 ulong	1	header_key	self pointer (to this block)
        8/ 0x08	ulong	1	high_seq	number of data block ptr stored here
       12/ 0x0c ulong	1	data_size	unused (==0)
       16/ 0x10	ulong	1	first_data	first data block ptr
       20/ 0x14	ulong	1	chksum		same algorithm as rootblock
       24/ 0x18 ulong	*	data_blocks[]	data blk ptr (first at BSIZE-204 )
        	                                * = (BSIZE/4) - 56
BSIZE-200/-0xc8	ulong	1 	UNUSED 		== 0
BSIZE-196/-0xc4	ushort	1 	UID 		UserID
BSIZE-194/-0xc4	ushort	1 	GID 		GroupID
BSIZE-192/-0xc0	ulong	1	protect		protection flags (set to 0 by default)

                                        Bit     If set, means

                                           If MultiUser FileSystem : Owner
					0	delete forbidden (D)
					1	not executable (E)
					2	not writable (W)
					3	not readable (R)

					4	is archived (A)
					5	pure (reetrant safe), can be made resident (P)
					6	file is a script (Arexx or Shell) (S)
					7	Hold bit. if H+P (and R+E) are set the file
                                                 can be made resident on first load (OS 2.x and 3.0)

                                        8       Group (D) : is delete protected 
                                        9       Group (E) : is executable 
                                       10       Group (W) : is writable 
                                       11       Group (R) : is readable 

                                       12       Other (D) : is delete protected 
                                       13       Other (E) : is executable 
                                       14       Other (W) : is writable 
                                       15       Other (R) : is readable 
                                    30-16	reserved
				       31	SUID, MultiUserFS Only

BSIZE-188/-0xbc	ulong	1	byte_size	file size in bytes
BSIZE-184/-0xb8	char	1	comm_len	file comment length
BSIZE-183/-0xb7	char	79	comment[]	comment (max. 79 chars permitted)
BSIZE-104/-0x69	char	12	UNUSED		set to 0
BSIZE- 92/-0x5c	ulong	1	days		last change date (days since 1 jan 78)
BSIZE- 88/-0x58	ulong	1	mins		last change time
BSIZE- 84/-0x54	ulong	1	ticks		 in 1/50s of a seconds
BSIZE- 80/-0x50	char	1	name_len	filename length
BSIZE- 79/-0x4f char	30	filename[]	filename (max. 30 chars permitted)	
BSIZE- 49/-0x31 char	1	UNUSED		set to 0
BSIZE- 48/-0x30 ulong	1	UNUSED		set to 0
BSIZE- 44/-0x2a	ulong	1	real_entry	FFS : unused (== 0)
BSIZE- 40/-0x28	ulong	1	next_link	FFS : hardlinks chained list (first=newest)
BSIZE- 36/-0x24	ulong	5	UNUSED		set to 0
BSIZE- 16/-0x10	ulong	1	hash_chain	next entry ptr with same hash
BSIZE- 12/-0x0c	ulong	1	parent		parent directory
BSIZE-  8/-0x08	ulong	1	extension	pointer to 1st file extension block
BSIZE-  4/-0x04	ulong	1	sec_type	secondary type : ST_FILE (== -3)
------------------------------------------------------------------------------------------------

As with volume names ':' and '/' are forbidden in file names.

The number of blocks used to store a file depends on the filesystem used, OFS or FFS. If one file has 7 datablocks, the first is at datablock[71-0], the last at datablocks[71-6], and highseq equals to 7.

For the OFS there are two ways of reading the contents of a file. First by traversing the linked list of data blocks that is pointed to in first_data (offset 16) and then following the pointers in each file data block. The other way of accessing the file data is by using the data_blocks[] table and going backwards through the data blocks listed there and then the File extension blocks.

As the FFS doesn't contain extra information in the data blocks (no pointer list, no checksum) the only way of accessing the file contents is by going through the data_blocks[] table and the File extension blocks.

An empty file consists of just a File header block, with 'byte_size' equal to 0, and no Data block pointers in 'data_blocks[]'.

* File extension block (BSIZE bytes) (first pointer in File header)
------------------------------------------------------------------------------------------------
        0/ 0x00	ulong	1	type		primary type : T_LIST (== 16)
        4/ 0x04	ulong	1	header_key	self pointer
        8/ 0x08	ulong	1	high_seq	number of data blk ptr stored
       12/ 0x0c	ulong	1	UNUSED		unused (== 0)
       16/ 0x10	ulong	1	UNUSED		unused (== 0)
       20/ 0x14	ulong	1	chksum		rootblock algorithm
       24/ 0x18	ulong	*	data_blocks[]	data blk ptr (first at BSIZE-204)
        	                                * = (BSIZE/4) - 56
BSIZE-200/-0xc8	ulong	46	info		unused (== 0)
BSIZE- 16/-0x10	ulong	1	UNUSED		unused (== 0)
BSIZE- 12/-0x0c	ulong	1	parent		file header block
BSIZE-  8/-0x08	ulong	1	extension	next file header extension block, 
	                                        0 for the last
BSIZE-  4/-0x04	ulong	1	sec_type	secondary type : ST_FILE (== -3)
------------------------------------------------------------------------------------------------
* Data blocks (BSIZE bytes) (first pointer in File header 'first_data' and 'data_blocks[((BSIZE/4)-57)]')
Old File System data block (BSIZE bytes)
-------------------------------------------------------------------------------
0/0	ulong	1	type		primary type : T_DATA (== 8)
4/4	ulong	1	header_key	pointer to file header block
8/8	ulong	1	seq_num		file data block number (first is #1) 
12/c	ulong	1	data_size	data size <= (BSIZE-24)
16/10	ulong	1	next_data	next data block ptr (0 for last)
20/14	ulong	1	chksum		rootblock algorithm
24/18	UCHAR	*	data[]		file data size <= (BSIZE-24)
-------------------------------------------------------------------------------
In OFS, there is a second way to read a file : using the Data block chained list. The list starts in File header ('first_data') and goes on with 'next_data' in each Data block.

Fast File System (BSIZE bytes)
-------------------------------------------------------------------------------
0/0	UCHAR	BSIZE	data[]		file data
-------------------------------------------------------------------------------
In FFS, the only way to read or recover a file is to use data_blocks[] in the file header block and the File extension blocks. If a File header or File extension block is unreadable, there is no way to find the corresponding Data blocks.

The OFS is more robust than FFS, but slower and can store less data on disk. As you see, disk salvaging is easier with OFS.

When a file is deleted, only its File header block number is cleared from the Directory block (or from the same-hash-value list) and the bitmap is updated. File header block, Data blocks and File extension blocks are not cleared, but the bitmap blocks are updated. Nevertheless, the undelete operation is easy, as long as these blocks are not overwritten.


4.5 How are directories stored?

Directory blocks are very similar to Rootblock, except they don't need information about the bitmap and disk, but they allow comments like files.
* User directory block (BSIZE bytes)
------------------------------------------------------------------------------------------------
        0/ 0x00	ulong	1	type		block primary type = T_HEADER (value 2)
        4/ 0x04	ulong	1	header_key	self pointer
	8/ 0x08	ulong 	3 	UNUSED		unused (== 0)
       20/ 0x14	ulong	1	chksum		normal checksum algorithm
       24/ 0x18	ulong	*	ht[]		hash table (entry block number)
        	                                * = (BSIZE/4) - 56
                	                        for floppy disk: size= 72 longwords
BSIZE-200/-0xc8	ulong	2	UNUSED		unused (== 0)
BSIZE-196/-0xc8	ushort	1 	UID 		User ID
BSIZE-194/-0xc8	ulong	1	GID		Group ID
BSIZE-192/-0xc0	ulong	1	protect		protection flags (set to 0 by default)

                                        Bit     If set, means

                                           If MultiUser FileSystem : Owner
					0	delete forbidden (D)
					1	not executable (E)
					2	not writable (W)
					3	not readable (R)

					4	is archived (A)
					5	pure (reetrant safe), can be made resident (P)
					6	file is a script (Arexx or Shell) (S)
					7	Hold bit. if H+P (and R+E) are set the file
                                                 can be made resident on first load (OS 2.x and 3.0)

                                        8       Group (D) : is delete protected 
                                        9       Group (E) : is executable 
                                       10       Group (W) : is writable 
                                       11       Group (R) : is readable 

                                       12       Other (D) : is delete protected 
                                       13       Other (E) : is executable 
                                       14       Other (W) : is writable 
                                       15       Other (R) : is readable 
                                    30-16	reserved
				       31	SUID, MultiUserFS Only

BSIZE-188/-0xbc	ulong	1	UNUSED		unused (== 0)
BSIZE-184/-0xb8	char	1	comm_len	directory comment length
BSIZE-183/-0xb7	char	79	comment[]	comment (max. 79 chars permitted)
BSIZE-104/-0x69	char	12	UNUSED		set to 0
BSIZE- 92/-0x5c	ulong	1	days		last access date (days since 1 jan 78)
BSIZE- 88/-0x58	ulong	1	mins		last access time
BSIZE- 84/-0x54	ulong	1	ticks		in 1/50s of a seconds
BSIZE- 80/-0x50	char	1	name_len	directory name length
BSIZE- 79/-0x4f char	30	dirname[]	directory (max. 30 chars permitted)	
BSIZE- 49/-0x31 char	1	UNUSED		set to 0
BSIZE- 48/-0x30 ulong	2	UNUSED		set to 0
BSIZE- 40/-0x28	ulong	1	next_link	FFS : hardlinks chained list (first=newest)
BSIZE- 36/-0x24	ulong	5	UNUSED		set to 0
BSIZE- 16/-0x10	ulong	1	hash_chain	next entry ptr with same hash
BSIZE- 12/-0x0c	ulong	1	parent		parent directory
BSIZE-  8/-0x08	ulong	1	extension	FFS : first directory cache block
BSIZE-  4/-0x04	ulong	1	sec_type	secondary type : ST_USERDIR (== 2)
------------------------------------------------------------------------------------------------
You can obtain a directory listing exactly like with the root directory.


4.6 How are links implemented in AmigaDOS ?

With the FFS, links were introduced. Alas, Commodore blundered again: soft like where terribly broken, so they removed support for them in AmigaDOS 3.0. Hard links are seen as files, and hard links to directories are allowed, which opens the way to endless recursion...
In short, the whole implmentation is a mess.
However, some shells (like Csh 5.37) support them, so I'm supplying the structure.

4.6.1 Hard links

* Hard link (BSIZE bytes)
------------------------------------------------------------------------------------------------
        0/ 0x00	ulong	1	type		block primary type = T_HEADER (value 2)
        4/ 0x04	ulong	1	header_key	self pointer
	8/ 0x08	ulong 	3 	UNUSED		unused (== 0)
       20/ 0x14	ulong	1	chksum		normal checksum algorithm
       24/ 0x18	ulong	*	UNUSED		set to 0
        	                                * = (BSIZE/4) - 54
                	                        for floppy disk: size= 74 longwords
BSIZE-192/-0xc0	ulong	1	protect		protection flags (set to 0 by default)

                                        Bit     If set, means

                                           If MultiUser FileSystem : Owner
					0	delete forbidden (D)
					1	not executable (E)
					2	not writable (W)
					3	not readable (R)

					4	is archived (A)
					5	pure (reetrant safe), can be made resident (P)
					6	file is a script (Arexx or Shell) (S)
					7	Hold bit. if H+P (and R+E) are set the file
                                                 can be made resident on first load (OS 2.x and 3.0)

                                        8       Group (D) : is delete protected 
                                        9       Group (E) : is executable 
                                       10       Group (W) : is writable 
                                       11       Group (R) : is readable 

                                       12       Other (D) : is delete protected 
                                       13       Other (E) : is executable 
                                       14       Other (W) : is writable 
                                       15       Other (R) : is readable 
                                    30-16	reserved
				       31	SUID, MultiUserFS Only

BSIZE-188/-0xbc	ulong	1	UNUSED		unused (== 0)
BSIZE-184/-0xb8	char	1	comm_len	comment length
BSIZE-183/-0xb7	char	79	comment[]	comment (max. 79 chars permitted)
BSIZE-104/-0x69	char	12	UNUSED		set to 0
BSIZE- 92/-0x5c	ulong	1	days		last access date (days since 1 jan 78)
BSIZE- 88/-0x58	ulong	1	mins		last access time
BSIZE- 84/-0x54	ulong	1	ticks		in 1/50s of a seconds
BSIZE- 80/-0x50	char	1	name_len	hard link name length
BSIZE- 79/-0x4f char	30	hlname[]	hardlink name (max. 30 chars permitted)	
BSIZE- 49/-0x31 char	1	UNUSED		set to 0
BSIZE- 48/-0x30 ulong	1	UNUSED		set to 0
BSIZE- 44/-0x2c	ulong	1	real_entry	FFS : pointer to "real" file or directory
BSIZE- 40/-0x28	ulong	1	next_link	FFS : hardlinks chained list (first=newest)
BSIZE- 36/-0x24	ulong	5	UNUSED		set to 0
BSIZE- 16/-0x10	ulong	1	hash_chain	next entry ptr with same hash
BSIZE- 12/-0x0c	ulong	1	parent		parent directory
BSIZE-  8/-0x08	ulong	1	UNUSED		set to 0
BSIZE-  4/-0x04	ulong	1	sec_type	secondary type : ST_LINKFILE = -4
						ST_LINKDIR = 4
------------------------------------------------------------------------------------------------
A 'real' entry is a file or directory entry, opposed to link entries.

A hard link can only be created to the same disk as the real entry disk. Several links can be made on the same real entry. These are in just another linked list.
'real entry' always contains the real entry block pointer.
'next_link' stores the links linked list.

New entries are added at the head:

>ls
  ------rw-d     1912  15-May-96 22:28:08  real
Chained list state :
block# real	next	name
----------------------------
484	0	0	real


>ln real link1
>ls
  ------rw-d     1912  15-May-96 22:28:08  real
  -H----rw-d     1912  15-May-96 22:28:10  link1 -> Empty:real

block# real	next	name
----------------------------
484	0	104	real
104	484	0	link1


>ln link1 link2
>ls
  ------rw-d     1912  15-May-96 22:28:08  real
  -H----rw-d     1912  15-May-96 22:28:10  link1 -> Empty:real
  -H----rw-d     1912  15-May-96 22:28:12  link2 -> Empty:real

block# real	next	name
----------------------------
484	0	107	real
104	484	0	link1
107	484	104	link2
The links are stored 'newest first', due to the adding at head.

real -> newest link -> ... -> oldest link -> 0

-> means "points to"

4.6.2 Soft links

* Soft link (BSIZE bytes)
------------------------------------------------------------------------------------------------
        0/ 0x00	ulong	1	type		block primary type = T_HEADER (value 2)
        4/ 0x04	ulong	1	header_key	self pointer
	8/ 0x08	ulong 	3 	UNUSED		unused (== 0)
       20/ 0x14	ulong	1	chksum		normal checksum algorithm
       24/ 0x18	ulong	*	symbolic_name	path name to referenced object, Cstring
        	                                * = ((BSIZE - 224) - 1)
                	                        for floppy disk: size= 288 - 1 chars
BSIZE-200/-0xc8	ulong	2	UNUSED		unused (== 0)
BSIZE-192/-0xc0	ulong	1	protect		protection flags (set to 0 by default)

                                        Bit     If set, means

                                           If MultiUser FileSystem : Owner
					0	delete forbidden (D)
					1	not executable (E)
					2	not writable (W)
					3	not readable (R)

					4	is archived (A)
					5	pure (reetrant safe), can be made resident (P)
					6	file is a script (Arexx or Shell) (S)
					7	Hold bit. if H+P (and R+E) are set the file
                                                 can be made resident on first load (OS 2.x and 3.0)

                                        8       Group (D) : is delete protected 
                                        9       Group (E) : is executable 
                                       10       Group (W) : is writable 
                                       11       Group (R) : is readable 

                                       12       Other (D) : is delete protected 
                                       13       Other (E) : is executable 
                                       14       Other (W) : is writable 
                                       15       Other (R) : is readable 
                                    30-16	reserved
				       31	SUID, MultiUserFS Only

BSIZE-188/-0xbc	ulong	1	UNUSED		unused (== 0)
BSIZE-184/-0xb8	char	1	comm_len	comment length
BSIZE-183/-0xb7	char	79	comment[]	comment (max. 79 chars permitted)
BSIZE-104/-0x69	char	12	UNUSED		set to 0
BSIZE- 92/-0x5c	ulong	1	days		last access date (days since 1 jan 78)
BSIZE- 88/-0x58	ulong	1	mins		last access time
BSIZE- 84/-0x54	ulong	1	ticks		in 1/50s of a seconds
BSIZE- 80/-0x50	char	1	name_len	soft link name length
BSIZE- 79/-0x4f char	30	slname[]	softlink name (max. 30 chars permitted)	
BSIZE- 49/-0x31 char	1	UNUSED		set to 0
BSIZE- 48/-0x30 ulong	8	UNUSED		set to 0
BSIZE- 16/-0x10	ulong	1	hash_chain	next entry ptr with same hash
BSIZE- 12/-0x0c	ulong	1	parent		parent directory
BSIZE-  8/-0x08	ulong	1	UNUSED		set to 0
BSIZE-  4/-0x04	ulong	1	sec_type	secondary type : ST_SOFTLINK = 3
------------------------------------------------------------------------------------------------

4.7 How are the blocks associated with the directory cache mode ?

To speed up directory listing, Directory cache blocks have been created.
Directory cache blocks are also organised in chained lists.
The list starts at the directory block (root or normal directory) with the 'extension' field.
* Directory cache block (BSIZE bytes)
-------------------------------------------------------------------------------
0/0	ulong	1	type		DIRCACHE == 33 (0x21)
4/4	ulong	1	header_key	self pointer
8/8	ulong	1	parent		parent directory
12/c	ulong	1	records_nb	directory entry records in this block
16/10	ulong	1	next_dirc	dir cache chained list
20/14	ulong	1	chksum		normal checksum
24/18	UCHAR	*	records[]	entries list (size = BSIZE-24)
-------------------------------------------------------------------------------
The directory entries are stored this way :
* Directory cache block entry record (26 <= size (in bytes) <= 77)
-------------------------------------------------------------------------------
0	ulong	1	header		entry block pointer
                                        (the link block for a link)
4	ulong	1	size		file size (0 for a directory or a link)
8	ulong	1	protect		protection flags (0 for a link ?)
					 (see file header or directory blocks)
12	ushort	1	UID             user ID
14 	ushort 	1 	GID 		group ID
16	short	1	days		date (always filled)
18	short	1	mins		time (always filled)
20	short	1	ticks
22	char	1	type		secondary type
23	char	1	name_len	1 <= len <= 30 (nl)
24	char	?	name		name
24+nl	char	1	comm_len	0 <= len <= 22 (cl)
25+nl	char	?	comment		comment
25+nl+cl char	1	OPTIONAL padding byte(680x0 longs must be word aligned)
-------------------------------------------------------------------------------

5. How does a blank disk look like ?

A minimal blank disk has a Bootblock, a Rootblock and a Bitmap block.

5.1 a Minimal blank floppy disk

* The Bootblock (0 and 1)

0	char	4	ID		'D''O''S' + flags
4	long	1023	full of zeros


* The Rootblock (880)

0	long	1	type		2
12/c	long	1	ht_size		0x48
20/14	long	1	checksum	computed
312/138	long	1	bm_flag		-1 (valid bitmap)
316/13c	long	1	bm_pages[0]	bitmap sector #
420/1a4	long	1	last access date
424/1a8	long	1	last access time
428/1ac	long	1	last access time
432/1b0	char	1	disk_name size
433/1b1	char	?	disk_name
472/1d8	long	1	last access date
476/1dc	long	1	last access time
480/1e0	long	1	last access time
484/1e4 long    1       creation date
488/1e8 long    1       creation time
492/1ec long    1       creation time
504/1f8	long	1	FFS : first dir cache sector  or 0
508/1fc	long	1	sub_type	1

Unspecified fields are set to 0.


* The Bitmap block (here 881) for a DD disk

0	long	1	checksum
4	long	27	free sectors	0xffffffff
112/70	long	1	root+bitmap	0xffff3fff
116/74	long	27	free sectors	0xffffffff
120/78	long	72	unused		!=0

5.2 A 'Bootable' floppy disk

* The Bootblock becomes :
0/0x00	long	1	ID		'D''O''S' + flags
4/0x04	long	1	checksum	computed
8/0x08	long	1	rootblock ?	880
12/0x0c	byte	81	bootcode	AmigaDOS 3.0 version

	values			disassembled
	--------------+---------------------
	43FA003E		lea	exp(pc),a1	;Lib name
	7025			moveq	#37,d0		;Lib version
	4EAEFDD8		jsr	-552(a6)	;OpenLibrary()
	4A80			tst.l	d0		;error == 0
	670C			beq.b	error1
	2240			move.l	d0,a1		;lib pointer
	08E90006 0022		bset	#6,34(a1)	;(*)
	4EAEFE62		jsr	-414(a6)	;CloseLibrary()
	43FA0018	error1:	lea	dos(PC),a1	;name
	4EAEFFA0		jsr	-96(a6)		;FindResident()
	4A80			tst.l	d0
	670A			beq.b	error2		;not found
	2040			move.l	d0,a0
	20680016		move.l	22(a0),a0	;DosInit sub
	7000			moveq	#0,d0
	4E75			rts
	70FF		error2:	moveq	#-1,d0
	4E75			rts
	646F732E 6C696272 617279
			dos:	"dos.library"
	00						;padding byte
	65787061 6E73696F 6E2E6C69 62726172 79
			exp:	"expansion.library"

93/0x5d	byte	931	full of zeros
(*) from Thomas Kessler (tkessler@ra.abo.fi), may 1997 :
This bit tells the shell (which opens its shell-window when booting the startup-sequence) not to open window unless needed, so a black screen stays there during boot instead of an empty shell-windows (it's a os2.x feature).


5.3 A Directory cache mode floppy disk

* A directory cache block (here 882)

0	long	1	type		0x21
4	long	1	self pointer	882
8	long	1	cached dir	880 (root)
12/c	long	1	entries number	0
16/10	long	1	next dir cache	0 (last)
20/14	long	1	checksum	computed
24	long	122	full of zeros

5.4 International Mode

The toupper() function in the HashName() function (3.2.1 paragraph) is replaced by the following function with the aim of better handling international characters :
int intl_toupper(int c)
{
   return (c>='a' && c<='z') || (c>=224 && c<=254 && c!=247) ? c - ('a'-'A') : c ;
}
In the Amiga ASCII table, the international character codes are between 192 and 254. Uppercase caracters are between 192 and 222, the lowercase versions of them are between 224 and 254. The only exception are the codes 215 and 247, which are respectively the multiply sign and the divide sign.

The Amiga character set is the same as ISO 8859 Latin-1 character set, often assumed in HTML pages. This character set is described here : http://www.w3c.org/


6. The structure of a hard disk

The following structures are mainly extracted from the 'devices/hardblocks.h' and 'dos/filehandler.h' files delivered in Commodore developer kits.

The hard disk specific structures mainly store the drive geometry, the written partitions sizes and the filesystem bootcode.

The five kind of blocks are in a reserved area, at the beginning of the surface. The first of them, Rigid Disk block (RDSK), must be found within the first 16 blocks of BSIZE lenght. But it can be written inside the data area, which is dangerous.

6.1 What is the Rigid Disk Block ?

* Rigid Disk block (256 bytes) must exist within the first 16 blocks
-------------------------------------------------------------------------------
0/0	char	4	id		'RDSK'
4/4	ulong	1	size in longs 	== 64
8/8	long	1	checksum	classic Rootblock algorithm
12/c	ulong	1	hostID		SCSI Target ID of host
					(== 7 for IDE and ZIP disks)
16/10	ulong	1 	block size 	typically 512 bytes, but can
					be other powers of 2
20/14	ulong	1	flags 		typically 0x17
				Bit	If set means :
				0 	No disks exists to be configured 
					after this one on this controller
				1 	No LUNs exists to be configured greater
					than this one at this SCSI Target ID
				2 	No target IDs exists to be configured
					greater than this one on this SCSI bus
				3 	Don't bother trying to perform
					reselection when talking to this drive
				4 	Disk indentification valid
				5 	Controller indentification valid
				6 	Drive supports SCSI synchronous mode
					(can be dangerous if it doesn't)
24/18 	ulong 	1 	Bad blockList 	block pointer (-1 means last block)
28/1c 	ulong 	1 	PartitionList	block pointer (-1 means last)
32/20 	ulong 	1 	FileSysHdrList 	block pointer (-1 means last)
36/24 	ulong 	1 	DriveInit code 	optional drive-specific init code
					DriveInit(lun,rdb,ior) : 
					"C" stack and d0/a0/a1
40/28 	ulong 	6 	RESERVED 	== -1

	Physical drive caracteristics
64/40	ulong 	1 	cylinders 	number of drive cylinder
68/44 	ulong 	1 	sectors 	sectors per track
72/48	ulong 	1 	heads 		number of drive heads
76/4c 	ulong 	1 	interleave
80/50 	ulong 	1 	parking zone 	landing zone cylinders
					soon after the last cylinder
84/54 	ulong	3 	RESERVED 	== 0
96/60 	ulong 	1 	WritePreComp 	starting cyl : write precompensation
100/64	ulong 	1 	ReducedWrite 	starting cyl : reduced write current
104/68 	ulong 	1 	StepRate 	drive step rate
108/6c 	ulong 	5 	RESERVED 	== 0

	Logical drive caracteristics
128/80 	ulong 	1 	RDB_BlockLo 	low block of range reserved for hardblk
132/84 	ulong 	1 	RDB_BlockHi 	high block of range for this hardblocks
136/88 	ulong 	1 	LoCylinder 	low cylinder of partitionable disk area
140/8c 	ulong 	1 	HiCylinder 	high cylinder of partitionable data area
144/90 	ulong 	1 	CylBlocks 	number of blocks available per cylinder
148/94 	ulong 	1 	AutoParkSeconds zero for no autopark
152/98 	ulong 	1 	HighRSDKBlock 	highest block used by RDSK 
					(not including replacement bad blocks)
156/9c 	ulong 	1 	RESERVED 	== 0

	Drive identification
160/a0 	char 	8 	DiskVendor 	ie 'IOMEGA'
168/a8	char 	16 	DiskProduct 	ie 'ZIP 100'
184/b8	char 	4 	DiskRevision 	ie 'R.41'
188/bc 	char 	8 	ControllerVendor
196/c4 	char 	16 	ControllerProduct
212/d4 	char 	4 	ControllerRevision
216/d8 	ulong 	10 	RESERVED 	== 0
256/100
-------------------------------------------------------------------------------

* How to find the physical geometry of the disk ?

A hard disk is made of several physical disks. They have one head for each writable side. Each physical disk consists of several tracks, which consist of several sectors. One cylinder is the set of the tracks which have the same number on each disk.

The total size of the hard disk is expressed in cylinders ('cylinders').
The size of a cylinder is :
the number of heads per cylinder ('heads')
x the number of sectors per track ('sectors')
x the size of a block ('block size').

The 'CylBlocks' field equals to 'heads' x 'sectors'.

The reserved area is often the 2 first cylinders, between the 'RDB_BlockLo' block and the 'RDB_BlockHi' block, included. The partitionable area, starts at the 'LoCylinder' cylinder until the 'HiCylinder' cylinder, included.

The really last used sector in the reserved area is the sector numbered 'HighRSDKBlock', the first is numbered 0. The SCSI 'hostID' is set to the id of the SCSI host controller, which is typically 7. Real SCSI drives ID must be between 0 and 6.

The RDSK block is the "root" of the reserved area. It also contains the first blocks of three linked lists : one the bad blocks replacement, one for the partition definitions and one last for the filesystem information.

Some geometry examples :

  • a Zip disk : 2891 cylinders, 1 head, 68 sectors,
  • my 80Mb Seagate IDE harddisk : 980 cylinders, 10 heads, 17 sectors.
  • a 500 Mbyte Fujitsu 2624SA: 1472 cylinders, 11 heads, 63 sectors
  • a 50 Mbyte Quantum LPS52: 2085 cylinders, 1 head, 49 sectors


6.2 How are bad blocks managed ?

* Bad Block block (BSIZE bytes) first in RDSK 'BadBlockList' field
-------------------------------------------------------------------------------
0/0 	ulong 	1 	id 		'BADB'
4/4 	ulong 	1 	size in longs 	== 128 for BSIZE = 512
8/8 	long 	1 	checksum
12/c 	ulong 	1 	HostID 		== 7 ?
16/10 	ulong 	1 	next 		next BadBlock block
20/14 	ulong 	1 	RESERVED
24/18 	 	* 	BlockPairs[]	bad block entries table
					* size = ((BSIZE/4)-6)/2
					(for BSIZE=512 = 61*8 byte entries)
-------------------------------------------------------------------------------
* Bad Block entry (8 bytes) stored in BadBlock 'BlockPairs[]' field
-------------------------------------------------------------------------------
0/0 	ulong 	1 	BadBlock 	block number of bad block
4/4 	ulong 	1 	GoodBlock 	block number of replacement block
-------------------------------------------------------------------------------

6.3 How are partitions stored?

* Partition block (256 bytes) first in RDSK 'PartitionList' field
-------------------------------------------------------------------------------
0/0 	char 	4 	ID 		'PART'
4/4 	ulong 	1 	size in long 	of checksummed structure (== 64)
8/8 	ulong 	1 	checksum        classic algorithm
12/c 	ulong 	1 	hostID 		SCSI Target ID of host (== 7)
16/10 	ulong 	1 	next 		block number of the next Partitionblock
20/14 	ulong 	1 	Flags
				Bit 	If set means
				0 	This partition is bootable
				1 	No automount
24/18 	ulong 	2 	RESERVED
32/20 	ulong 	1 	DevFlags 	preferred flags for OpenDevice
36/24 	char 	1 	DriveName len 	length of Drive name (e.g. 3)
37/25	char 	31 	DriveName 	e.g. 'DH0'
68/44 	ulong 	15 	RESERVED

	DOS Environment vector (DOSEnvVec) (often defined in MountLists)
128/80 	ulong 	1 	size of vector 	== 16 (longs), 11 is the minimal value
132/84 	ulong 	1 	SizeBlock	size of the blocks in longs ==
					128 for BSIZE = 512
136/88 	ulong 	1 	SecOrg 		== 0
140/8c 	ulong 	1 	Surfaces 	number of heads (surfaces) of drive
144/90 	ulong 	1 	sectors/block 	sectors per block == 1
148/94 	ulong 	1 	blocks/track 	blocks per track
152/98 	ulong 	1 	Reserved 	DOS reserved blocks at start of partition
                                        usually = 2 (minimum 1)
156/9c 	ulong 	1 	PreAlloc 	DOS reserved blocks at end of partition
					(no impact on Root block allocation)
					normally set to == 0
160/a0 	ulong 	1 	Interleave 	== 0
164/a4 	ulong 	1 	LowCyl		first cylinder of a partition (inclusive)
168/a8 	ulong 	1 	HighCyl		last cylinder of a partition (inclusive)
172/ac 	ulong 	1 	NumBuffer 	often 30 (used for buffering)
176/b0 	ulong 	1 	BufMemType 	type of mem to allocate for buffers ==0
180/b4 	ulong 	1 	MaxTransfer 	max number of type to transfer at a type
					often 0x7fff ffff
184/b8 	ulong 	1 	Mask 		Address mask to block out certain memory
					often 0xffff fffe
188/bc 	ulong	1 	BootPri 	boot priority for autoboot
192/c0 	char	4	DosType 	'DOS' and the FFS/OFS flag only
					also 'UNI'\0 = AT&T SysV filesystem
					'UNI'\1 = UNIX boot filesystem
					'UNI'\2 = BSD filesystem for SysV
					'resv' = reserved (swap space)
196/c4  ulong	1	Baud 		Define default baud rate for Commodore's
					SER and AUX handlers, originally
					used with the A2232 multiserial board
200/c8  ulong	1	Control		used by Commodore's AUX handler
204/cc  ulong	1	Bootblocks	Kickstart 2.0: number of blocks
					containing boot code to be
					loaded at startup
208/d0	ulong	12 	RESERVED
-------------------------------------------------------------------------------
There exists one 'PART' block per partition.

The block pointers in the reserved area are relative to the beginning of the media. The block pointers in a partition are relative to the first block of the partition.

The Rootblock of a partition is normally located in the middle of an AmigaDOS filesystem. Please see 4.2 What is a Rootblock? for the exact calculation of it's location.

The first two blocks of a partition contain a Bootblock. You have to use it to determine the correct file system, and if the international or dircache modes are used. Don't rely only on the PART and FSHD 'DosType' field.


6.4 What are FSHD blocks ?

* Filesystem header block (256 bytes) first in RSDK 'FileSysHeaderList'
-------------------------------------------------------------------------------
0/0 	char 	4 	id 		'FSHD'
4/4 	ulong 	1 	size in longs 	== 64
8/8 	long 	1 	checksum        classic algorithm
12/c 	ulong 	1 	hostID 		SCSI Target ID of host (often 7)
16/10 	ulong 	1 	next 	 	block number of next FileSysHeaderBlock
20/14 	ulong 	1 	flags
24/18 	ulong 	2 	RESERVED
32/20 	char 	4 	DosType 	'DOS' and OFS/FFS DIRCACHE INTL bits
36/24 	ulong 	1 	Version 	filesystem version 0x0027001b == 39.27
40/28 	ulong 	1 	PatchFlags 	bits set for those of the following
					that need to be substituted into a
 					standard device node for this 
					filesystem : e.g. 0x180 to substitute
					SegList and GlobalVec
	Device node
44/2c 	ulong 	1 	Type 		device node type == 0
48/30 	ulong 	1 	Task 		standard DOS "task" field == 0
52/34	ulong 	1 	Lock 		not used == 0
56/38 	ulong 	1 	Handler 	filename to loadseg == 0
60/3c 	ulong 	1 	StackSize 	stacksize to use when starting task ==0
64/40 	ulong 	1 	Priority 	task priority when starting task == 0
68/44 	ulong 	1 	Startup 	startup msg == 0
72/48 	ulong 	1 	SegListBlock 	first of linked list of LoadSegBlocks :
					note that this entry requires some
 					processing before substitution
76/4c 	ulong 	1 	GlobalVec 	BCPL global vector when starting task =-1
80/50 	ulong 	23 	RESERVED 	by PatchFlags
172/ac 	ulong 	21 	RESERVED
-------------------------------------------------------------------------------
This block contains information on how to lauch the task which will manage the filesystem. You don't need it to reach partitions.

6.5 What are LSEG blocks ?

* LoadSeg block (BSIZE bytes) first in FileSysHeaderBlock 'SegListBlocks' field
-------------------------------------------------------------------------------
0/0 	char 	4 	id 		'LSEG'
4/4 	long 	* 	size in longs 	size of this checksummed structure
					* size = BSIZE/4
8/8 	long 	1 	checksum 	classic checksum
12/c 	long 	1 	hostID 		SCSI Target ID of host (often 7)
16/10 	long 	1 	next 		block number of the next LoadSegBlock
                                        (-1 for the last)
20/14 	uchar 	* 	LoadData[] 	code stored like an executable, with
					relocation hunks
					* size = ((BSIZE/4) - 5)
-------------------------------------------------------------------------------
This block contains the code of the filesystem. It isn't needed to reach partitions.

7. The Hard file : a big floppy dump file

A hardfile is a file which contains an Amiga volume.

It is created with WinUAE (http://www.winuae.net/), and not the Amiga and the AmigaDOS. WinUAE is able to produce an empty file with random contents of a choosen size, often several megabytes long.
Under WinUAE, a AmigaDOS device appears, associated with the uaehf.device (UAE hardfile). You have to format it with the Workbench, and you obtain an 'hardfile'. This volume is then usable inside the emulator by AmigaDOS (it should also be mountable under Linux with the AFFS filesystem).

For example a 8Mb hardfile could be mounted on a kickstart 1.3 Amiga with the following mountlist (from uae docs/README) :

UAE0:  Device = uaehf.device
	   Unit   = 0
	   Flags  = 0
	   Surfaces  = 1
	   BlocksPerTrack = 32
	   Reserved = 1
	   Interleave = 0
	   LowCyl = 0  ;  HighCyl = 511
	   Buffers = 5
	   DosType = 0x444F5300
	   BufMemType = 1
An hardfile is like a floppy disk dump, but bigger : it has a bootblock, a rootblock, a bitmap and perhaps dircache blocks.
The first three bytes of a hardfile is then 'D' 'O' 'S'.

The geometry is : heads = 1, sectors = 32, 'cylinders' depends the hardfile size.


8. Advanced information

Bitmap related

* Bitmap allocation starts at root block, upto highest block. The next allocated blocks are located just after boot blocks and finally the last allocated block is the sector before root block.

root -> max -> boot+1 -> root-1

-> means "followed on disk by"

If you free some blocks by deleting a file, for example, the first next used block will be the first free block encountered starting from the Rootblock. The just freed blocks will be reused. It means that when you delete a file and you want to recover it, don't write anything else to the disk.
This strategy must have been chosen to minimize fragmentation.

Files related

* The order in which data and file extension blocks for a given file are written on disk differs with OFS and FFS.

  • OFS & FFS : All the data blocks of the file header block are written first.
  • FFS : Then follow all the file extension blocks of the file, then all the remaining data blocks are written.
    OFS : Each file extension block is followed by the related data blocks. So the last extension block is followed by the remaining data blocks.

OFS:
header -> data blocks -> ext. block -> data blocks -> ext. block -> data blocks

FFS:
header -> data blocks -> all ext. block -> all remaining data blocks

-> means "followed on disk by"

This difference is probably the main reason why FFS is faster then OFS.

Under FFS, the hash chains are sorted by block number.

Comparison chart of the ADF logical blocks

			    root  dir 	fileh 	hlink 	slink 	fext	data 	dirc
----------------------------------------------------------------------------------------
        0/ 0x00 1st_type    2 	  2 	2 	2 	2 	16	8 	33
        4/ 0x04 header_key  / 	  x 	x 	x 	x 	x 	x 	x
        8/ 0x08  	    / 	  / 	nb_blo	/ 	/ 	nb_blo 	block# 	PARENT
       12/ 0x0c table_size  72 	  / 	/ 	/ 	/ 	/ 	nb_data nb_rec
       16/ 0x10 list 	    / 	  / 	data#1 	/ 	/ 	/ 	next 	next
       20/ 0x14 chksum 	    x 	  x 	x 	x 	x 	x 	x 	x
       24/ 0x18 table 	    ht 	  ht 	blocks 	/ 	/ 	blocks  data 	records
    ...
BSIZE-184/-0xb8	comment_len /	  x 	x 	/ 	/ 	/ 	/ 	/
BSIZE-183/-0xb7 comment     /	  x 	x 	/ 	/ 	/ 	/ 	/
    ...
BSIZE- 92/-0x5c	days 	    x	  x	x 	x 	x 	/ 	/ 	/
BSIZE- 88/-0x58 mins 	    x	  x	x 	x 	x 	/ 	/ 	/
BSIZE- 84/-0x54 ticks 	    x	  x	x 	x 	x 	/ 	/ 	/
BSIZE- 80/-0x50	name_len    x 	  x 	x 	x 	x 	/ 	/ 	/
BSIZE- 79/-0x4f name 	    x 	  x 	x 	x 	x 	/ 	/ 	/
    ...
BSIZE- 16/-0x10	hash_chain  / 	  x 	x 			/ 	/ 	/
BSIZE- 12/-0x0c	parent	    / 	  x 	x 	x 	x 	fhdr 	/ 	/
BSIZE-  8/-0x08	extension   cache cache	fext    / 	/ 	next 	/ 	/
BSIZE-  4/-0x04	2nd_type    1 	  2 	-3	-4/4 	3 	-3 	/ 	/
----------------------------------------------------------------------------------------

type of blocks :
 root=rootblock,  dir=directory,  fileh=file header,  fext=file extension,
 hlink=hard link,  slink=soft link,  dirc=directory cache,  data=OFS data.

special values :
 /=unused
 x=used
 next=next block of same type

How to rename an entry ?

  1. Compute the new hashvalue
  2. Move the first sector pointer from the old hashvalue index to the new one
  3. Change the name in the directory or file header block

9. References and links

* ASM Sources:

  • Scoopex and Crionics disassembled demo hardloaders
  • 'the floppy disk book' copier source file, DATA BECKER books, 1988
* On-Line material :
* Books :
  • The Amiga Guru Book, Chapter 15, Ralph Babel, 1993
  • Rom Kernel Reference Manual : Hardware, pages 235-244, Addison Wesley
  • Rom Kernel Reference Manual : Libraries and Devices, Appendix C, Addison Wesley
  • La Bible de l'Amiga, Dittrich/Gelfand/Schemmel, Data Becker, 1988.

The AmigaDOS reference manual probably contains a lot of information about Amiga file systems, but i don't own it (Addison Wesley). The most detailed information about AmigaDOS can be found in Ralph Babel's "Amiga Guru Book".


10. C routines : the ADF library

The ADFlib is a portable C library designed to manage Amiga formatted devices like harddisks and ZIP disks, or dump files of this kind of media via the .ADF format.

The API permits you to :

  • mount/unmount a device (real one or a dump file),
  • mount/unmount a volume (partition),
  • create/open/close/delete/move/undelete a file,
  • read/write bytes from/to a file,
  • create/delete/undelete a directory,
  • get directory contents, change current directory, get parent directory.

A callback system makes it easy to write a real device driver for any platform. The ADFOpus ( http://adfopus.sourceforge.net/) application (a useful Windows Explorer like for ADF files and devices), written by Dan Sutherlan is able to access from NT4 an 2.5 inches harddisk formatted under AmigaDOS.
The ADFView Windows Explorer shell extension (http://www.viksoe.dk/code/adfview.htm) written by Bjarke Viksoe is also using ADFlib. Hard-disks under W2000 are also supported.

See the 1.2 section to see how to obtain the package.


11. Other Amiga FileSystems

  • An Amiga filesystem for Linux 0.99pl2 by Ray Burr (read only, hard disk): ftp://tsx-11.mit.edu/pub/linux/patches/amigaffs.tar.Z
  • The AFFS filesystem inside the Linux kernel distribution by Hans-Joachim "JBHR" Widmaier (RDSK, links and international mode supported, dircache disks read-only): ftp://ftp.us.kernel.org in /usr/src/linux/fs/affs/
    Currently maintained by Roman Zippel (zippel@linux-m68k.org)
  • An .ADF manipulation package for DOS/Windows, "ADF-suite" (GUI, Shareware, no sources included):
    link broken

The .ADF format FAQ ends here ! unadf-0.7.11a/Faq/adf_info_V0_9.txt0000644000000000000000000010115410534557264015363 0ustar rootrootFrom: Laurent.Clevy@meteo.fr Newsgroups: comp.sys.amiga.programmer, comp.sys.amiga.misc, comp.os.linux.misc Subject: Amiga floppy disks format (AmigaDos file system - floppies) Followup-To: poster Summary: This document describes the AmigaDos File System for floppy disks only. Physical/Logical formats, OFS/FFS, Directory caching, Links, Checksums. Archive-name: amiga/amiga_floppy_format Last-modified: 28. May 1997 Version: 0.9 Copyright: (c) 1997 Laurent Clevy Maintainer: Laurent Clevy FAQ : The Amiga floppy disks format Laurent Clevy Laurent.Clevy@meteo.fr 25 avenue Aristide Briand 28000 Chartres France Disclaimer and copyright ------------------------ This document is Copyright (C) 1997 by Laurent Clevy, but may be freely distributed, provided the author name and addresses are included and no money is charged for this document. This document is provided "as is". No warranties are made as to its correctness. Amiga, AmigaDos are registred trademarks of Gateway 2000. Introduction ------------ This document purpose is to describe the Amiga floppy disk format. I don't found any document which explains this format in details. Because I wish this machine to be supported a long time, including via emulators, I decided to write this file, and supply C routines as examples. Corrections (including about my english) are very welcome. Unfortunately, I have no permanent e-mail address currently, the only way to touch me is by postmail. Index ----- 1. How bytes are physically read/written on disk ? 1.1 What is MFM ? 1.2 What is the physical track format ? 1.3 What is the physical sector format ? 1.4 How to decode MFM data ? 2. What is the Amiga floppy disk geometry ? 3. How is logically organised a Amiga floppy disk ? 3.1 What is a Bootblock ? 3.2 What is a Rootblock ? 3.2.1 How to find the first sector of a entry ? 3.2.2 How to list directory entries ? 3.2.3 How to compute the checksum ? 3.3 How is managed the free/used blocks list ? 3.3.1 How to compute bitmap checksum ? 3.3.2 What is the 'bm_ext' field in Rootblock ? 3.4 How are stored files on a disk ? 3.5 How are stored directories ? 3.6 How are implemented links with AmigaDos ? 3.6.1 Hard links 3.6.2 Soft links 3.7 How is the block associated to directory caching ? 4. What is a blank disk ? 4.1 a Minimal blank disk 4.2 A 'Bootable' disk 4.3 A Directory cache mode disk 5. References 6. C Routines 7. Other Amiga file systems 8. To do Conventions ----------- * In this document, hexadecimal values are written like in C : for example 0x0c is the decimal value 12. As the Amiga is a 680x0 based computer, integers that require more than one byte are stored on disk in 'Motorola order' : the most significant byte comes first, then the less significant bytes in descending order of significance (MSB LSB for two-byte integers, B3 B2 B1 B0 for four-byte integers). A byte is 8 bits long. The left bit of a byte is the 7th, the right bit is the 0th. A 'word' is a 2 bytes (16 bits) integer, a 'long' a 4 bytes (32 bits) integer. Values are unsigned unless otherwise noted. * A block pointer is the number of this block on the disk. Disk starts with the #0 block. * Hashing is a method to access tables : given a number or a string, a hash function gives a index into a table. * Chained lists are cells oriented data structures. Each cell contains a pointer to the next or previous cell or both, the last pointer is null. C example : struct lcell { char name[10]; /* contains next cell adress, or NULL if this cell is the last */ struct lcell* next_cell; }; * Names of blocks begin with a capital (Rootblock). Name of fields are noted between quotes ('field_name'). * All formats are described as tables, one rows per field. Here is an example with then well known beginning of GIF format : offset type length name comments ---------------------------------------------------------- 0 char 3 signature 'GIF' 3 char 3 version '87a' or '89a' 6 short 1 screen width 8 short 1 screen height 1. How bytes are physically read/written on disk ? ================================================= Most of PC-like floppy disk controllers (FDC) are not able to read Amiga disks, because Amiga physical floppy disk operations are made by a specific chip called "Paula". However, i'm supplying this information because it's hard to find out. If you only want to understand the UAE .adf format, you don't need to read this part. For classical floppy disk operations, Paula is set with the following parameters : - MFM encoding - Precompensation time : 0 nanosec - Controller clock rate : 2 microseconds per bit cell - Sync value = 0x4489 The controller is able to put the read/write heads on a cylinder, and is able to read with the lower or upper side head. A track of 0x1900 words is usually read. 1.1 What is MFM ? ----------------- Because bits can't be written with magnetic fields directly on disk, an encoding scheme is required. Amiga floppy disks are MFM (Modified Frequence Modulation) encoded. The MFM encoding scheme is : user's data bit MFM coded bits --------------- -------------- 1 01 0 10 if following a 0 data bit 0 00 if following a 1 data bit User data longs are splitted in two parts, a part with even bits part first, followed by a part with odd bits. 1.2 What is the physical track format ? --------------------------------------- Double density (DD) disks have 11 sectors per track, High density (DD) disks have 22. So a track consists of 11/22 MFM encoded sectors, plus inter-track-gap. Note that sectors are not written from 0 to 10/21, you must use the 'info' field to recreate orderly track in memory. Each track begins with the first sector, and ends the end of the last sector (11th with DD disks, 22th with HDs). Each sector starts with 2 synchronization words. The synchro value is 0x4489. 1.3 What is the physical sector format ? ---------------------------------------- Here it comes : 0/0x0 word 2 MFM value 0xAAAA AAAA SYNCHRONIZATION 4/0x4 word 1 MFM value 0x4489 6/0x6 word 1 MFM value 0x4489 HEADER 8/0x8 long 1 info (even bits) 12/0xc long 1 info (odd bits) decoded long is : 0xff TT SS SG TT = track number ( 3 means cyl 1, head 1) SS = sector number ( 0 -> 10/21 ) sectors are not orderly !!! SG = number of sector before gap (including current one) Example for cylinder 0, head 1 of a DD disk : 0xff010009 0xff010108 0xff010207 0xff010306 0xff010405 0xff010504 0xff010603 0xff010702 0xff010801 <-- inter-sector-gap here ! 0xff01090b (0xb means -1 ?) 0xff010a0a (0xa means -2 ?) 16/0x10 long 4 sector label (even) 32/0x20 long 4 sector label (odd) decoded value seems to be always 0 END OF HEADER 48/0x30 long 1 header checksum (even) 52/0x34 long 1 header checksum (odd) (computed on mfm longs, longs between offsets 8 and 44 == 2*(1+4) longs) 56/0x38 long 1 data checksum (even) 60/0x3c long 1 data checksum (odd) (from 64 to 1088 == 2*512 longs) DATA 64/0x40 long 512 coded data (even) 576/240 long 512 coded data (odd) 1088/440 END OF DATA 1.4 How to decode MFM data ? ---------------------------- the algorithm : #define MASK 0x55555555 /* 01010101 ... 01010101 */ unsigned long *p1; /* MFM coded data buffer (size == 2*data_size) */ unsigned long *q; /* decoded data buffer (size == data_size) */ unsigned long a,b; unsigned long chksum; int data_size; /* size in long, 1 for info, 4 for sector label */ chksum=0L; do times { a = *p1; /* even bits */ b = *(p1+data_size); /* odd bits */ chksum^=a; /* eor */ chksum^=b; *q = ( b & MASK ) | ( ( a & MASK ) << 1 ); /* MFM decoding */ p1++; q++; } chksum&=MASK; 2. What is the Amiga floppy disk geometry ? =========================================== Here follows the disk geometries for DD and HD. bytes/sector sector/cyl sides/cyl cyl/disk ------------------------------------------------------------------------ DD disks 512 11 2 80 HD disks 512 22 2 80 The relations between sectors, sides and cylinders are for a DD disk : Block sector side track ----------------------------- 0 0 0 0 1 1 0 0 2 2 0 0 ... 10 10 0 0 11 0 1 0 ... 21 10 1 0 22 0 0 1 .. 1759 10 1 79 A DD disk has 11*2*80=1760 (0 to 1759) blocks, a HD disk has 22*2*80=3520 blocks. Of course the file system uses some of them, even for a blank disk. As the next part deals with, at least 4 blocks are used, for 3 logical structures : bootblock (2), rootblock (1) and bitmap block (1). The length of .ADF files for a DD disk is then 512*11*2*80 = 901120 bytes. 3. How is logically organised a Amiga floppy disk ? =================================================== The logical low level object of a Amiga disk is the 'sector' (or 'block') : 512 consecutive bytes. Disk information is distribued in the Bootblocks, the Rootblock and Bitmap block(s). FFS has block structures to provide directory list caching and (hard) links : Directory cache blocks and Link blocks. Directory tree is stored with a Directory block for each node. Directory entries (files, directories and links) are stored with a table, and are accessed with hashing and chained lists. Files are stored with a File header block and Data blocks. File extension blocks are also used for files stored with more than 72 Data blocks. 3.1 What is a Bootblock ? ------------------------- The first object of an Amiga floppy is the Boot block. If the checksum and the DiskType are correct, the system will execute the bootblock code, at boot time, of course :-). A valid bootblock is written by the AmigaDos command 'install'. * BootBlock (1024 bytes) sectors 0 and 1 ------------------------------------------------------------------------------- offset size number name meaning ------------------------------------------------------------------------------- 0/0 char 4 DiskType 'D''O''S' + flags (0->5) flags = set clr 0 FFS OFS 1 INT NOINT 2 DIRC NODIRC 4/4 long 1 Chksum special checksum 8/8 long 1 Rootblock ==880 DD and HD 12/0x0c char 1012 Bootblock code (see 4.2 'Bootable disk' for more information) ------------------------------------------------------------------------------- The DiskType flag informs of the disk format. OFS = Old/Original File System, the first one. (AmigaDos 1.2) FFS = Fast File System (AmigaDos 2.04) INT = International characters Mode (AmigaDos 3.0). DIRC = stands for Directory Cache Mode (AmigaDos 3.0). This mode speeds up directory listing, but take some disk space. There are few differences between the two file systems. - OFS Datablock stores 488 bytes, FFS stores 512 bytes, - FFS supports directories caching, links and international mode, - the FFS is faster than OFS. The bootblock checksum algorithm follows : * in 68000 assembler : lea bootbuffer,a0 move.l a0,a1 clr.l 4(a1) ;clear the checksum move.w #256-1,d1 ;1024/4 times moveq #0,d0 lpchk: add.l (a0)+,d0 ;accumulation bcc.s jump ;if carry set, add 1 to checksum add.l #1,d0 jump: dbf d1,lpchk ;next long word not.l d0 move.l d0,4(a1) ;new checksum * in C : #include #define Short(p) ((p)[0]<<8 | (p)[1]) #define Long(p) (Short(p)<<16 | Short(p+2)) unsigned long newsum,d; unsigned char buf[1024]; /* contains bootblock */ int i; memset(buf+4,0,4); /* clear old checksum */ newsum=0L; for(i=0; i<256; i++) { d=Long(buf+i*4); if ( (ULONG_MAX-newsum) < d ) /* overflow */ newsum++; newsum+=d; } newsum=~newsum; 3.2 What is a Rootblock ? ------------------------- The Rootblock is at the middle of the media : block number 880 for DD disks, block 1760 for HDs. The Rootblock contains information about disk : its name, its formatting date, etc ... It also contains information to access the files/directories/links located at the root (Unix /) directory. * Rootblock (512 bytes) sector 880 for a DD disk, 1760 for a HD disk ------------------------------------------------------------------------------ 0/0 long 1 type block primary type = T_HEADER (value 2) 4/4 long 1 header_key unused in rootblock (value 0) long 1 high_seq unused (value 0) 12/c long 1 ht_size Hash table size in long (value 0x48) 16/10 long 1 first_data unused (value 0) 20/14 long 1 chksum sum to check block integrity 24/18 long 72 ht[] hash table (entry block number) 312/138 long 1 bm_flag bitmap flag, -1 means VALID 316/13c long 25 bm_pages[] bitmap blocks pointers (first at 0) 416/1a0 long 1 bm_ext first bitmap extension block (Hard disks only) ... 432/1b0 char 1 name_len; disk name length 433/1b1 char 30 diskname[] disk name ... 472/1d8 long 1 days last access date : days since 1 jan 1978 476/1dc long 1 mins minutes past midnight 480/1e0 long 1 ticks ticks (1/50 sec) past last minute 484/1e4 long 1 c_days creation date 488/1e8 long 1 c_mins 492/1ec long 1 c_ticks long 1 next_hash unused (value = 0) long 1 parent_dir unused (value = 0) 504/1f8 long 1 extension FFS: first directory cache block, 0 otherwise 508/1fc long 1 sec_type block secondary type = ST_ROOT (value 1) ------------------------------------------------------------------------------- 3.2.1 How to find the first sector of a directory entry ? --------------------------------------------------------- Given the name of a file/directory/link you compute its hash value with this algorithm : * The hash function : #include int HashName(char *name) { int hash; int i,l; l=hash=strlen(name); for(i=0; i