1 #include <clib/macros.h>
2 #include <devices/scsidisk.h>
3 #include <devices/trackdisk.h>
5 #include <dos/dosextens.h>
6 #include <dos/filehandler.h>
7 #include <exec/errors.h>
9 #include <exec/memory.h>
10 #include <proto/dos.h>
11 #include <proto/exec.h>
12 #include <proto/intuition.h>
16 #include "/fs/deviceio.h"
17 #include "/fs/deviceio_protos.h"
18 #include "/fs/cachedio_protos.h"
22 #include "/bitfuncs.c"
24 #define BLCKFACCURACY (5) /* 2^5 = 32 */
29 extern ULONG __asm
RANDOM(register __d0 ULONG
);
30 extern LONG __asm
STACKSWAP(void);
31 extern ULONG __asm
CALCCHECKSUM(register __d0 ULONG
,register __a0 ULONG
*);
32 extern ULONG __asm
MULU64(register __d0 ULONG
,register __d1 ULONG
,register __a0 ULONG
*);
33 extern WORD __asm
COMPRESSFROMZERO(register __a0 UWORD
*,register __a1 UBYTE
*,register __d0 ULONG
);
36 const char version
[]="\0$VER: SFSdumpblock 1.0 (" ADATE
")\r\n";
38 LONG
read2(ULONG block
);
39 BOOL
checkchecksum(void *buffer
);
40 void setchecksum(void *buffer
);
41 void dumpblock(ULONG block
, void *data
, ULONG bytes
);
42 ULONG
calculatechecksum(void *buffer
);
44 struct DosEnvec
*dosenvec
;
46 /* blocks_ = the number of blocks of something (blocks can contain 1 or more sectors)
47 block_ = a block number of something (relative to start of partition)
48 sectors_ = the number of sectors of something (1 or more sectors form a logical block)
49 sector_ = a sector number (relative to the start of the disk)
50 bytes_ = the number of bytes of something
51 byte_ = a byte number of something
52 shifts_ = the number of bytes written as 2^x of something
53 mask_ = a mask for something */
55 extern ULONG blocks_total
; /* size of the partition in blocks */
57 extern ULONG byte_low
; /* the byte offset of our partition on the disk */
58 extern ULONG byte_lowh
; /* high 32 bits */
59 extern ULONG byte_high
; /* the byte offset of the end of our partition (excluding) on the disk */
60 extern ULONG byte_highh
; /* high 32 bits */
62 extern ULONG bytes_block
; /* size of a block in bytes */
64 extern UWORD shifts_block
; /* shift count needed to convert a blockoffset<->byteoffset */
66 extern ULONG bufmemtype
;
71 struct RDArgs
*readarg
;
72 UBYTE
template[]="DEVICE=DRIVE/A,BLOCK/N/A,BINARY/S\n";
76 ULONG binary
;} arglist
={NULL
};
78 if((DOSBase
=(struct DosLibrary
*)OpenLibrary("dos.library",39))!=0) {
79 if((IntuitionBase
=(struct IntuitionBase
*)OpenLibrary("intuition.library",39))!=0) {
80 if((readarg
=ReadArgs(template,(LONG
*)&arglist
,0))!=0) {
82 UBYTE
*devname
=arglist
.device
;
92 dl
=LockDosList(LDF_DEVICES
|LDF_READ
);
93 if((dl
=FindDosEntry(dl
,arglist
.device
,LDF_DEVICES
))!=0) {
94 struct FileSysStartupMsg
*fssm
;
95 struct MsgPort
*msgport
;
97 fssm
=(struct FileSysStartupMsg
*)BADDR(dl
->dol_misc
.dol_handler
.dol_Startup
);
98 dosenvec
=(struct DosEnvec
*)BADDR(fssm
->fssm_Environ
);
101 UnLockDosList(LDF_DEVICES
|LDF_READ
);
103 if((initcachedio((UBYTE
*)BADDR(fssm
->fssm_Device
)+1, fssm
->fssm_Unit
, fssm
->fssm_Flags
, dosenvec
))==0) {
105 // setiocache(arglist.lines!=0 ? *arglist.lines : 128, arglist.readaheadsize!=0 ? *arglist.readaheadsize : 8192, FALSE); /* 1 MB for read-ahead cache, no copyback mode. */
107 if((buffer
=AllocVec(bytes_block
, bufmemtype
))!=0) {
109 /** *********************************************
110 * Here starts the code:
113 read2(*arglist
.block
);
115 if(arglist
.binary
!=0) {
116 Write(Output(), buffer
, bytes_block
);
119 if(checkchecksum(buffer
)!=DOSTRUE
) {
120 printf("Warning: Checksum of block %ld is wrong. It is 0x%08lx while it should be 0x%08lx.\n", *arglist
.block
, ((struct fsBlockHeader
*)buffer
)->checksum
, calculatechecksum(buffer
));
122 if(((struct fsBlockHeader
*)buffer
)->ownblock
!= *arglist
.block
) {
123 printf("Warning: Block %ld indicates that it is actually block %ld (ownblock is wrong!)\n", *arglist
.block
, ((struct fsBlockHeader
*)buffer
)->ownblock
);
125 dumpblock(*arglist
.block
,buffer
,bytes_block
);
129 * Here ends the code.
130 * ********************************************/
135 printf("Not enough memory\n");
142 Printf("Unknown device %s\n",arglist
.device
);
143 UnLockDosList(LDF_DEVICES
|LDF_READ
);
148 CloseLibrary((struct Library
*)IntuitionBase
);
150 CloseLibrary((struct Library
*)DOSBase
);
157 LONG
read2(ULONG block
) {
158 // return(transfer(DIO_READ, buffer, block, 1));
159 return(read(block
, buffer
, 1));
165 else if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
166 PutStr("\n***Break\n");
173 void dumpblock(ULONG block
, void *data
, ULONG bytes
) {
174 ULONG
*d
=(ULONG
*)data
;
175 UBYTE
*d2
=(UBYTE
*)data
;
179 if(bytes
<bytes_block
) {
180 printf("Dump of first %ld bytes of block %ld.\n",bytes
,block
);
183 printf("Dump of block %ld.\n",block
);
200 if(c
>=127 && c
<=160) {
208 printf("0x%04lx: %08lx %08lx %08lx %08lx %s\n",off
,d
[0],d
[1],d
[2],d
[3],s
);
218 LONG
req(UBYTE
*fmt
, UBYTE
*gads
, ... ) {
224 /* Simple requester function which is called by deviceio.o
225 for displaying low-level device errors and accesses outside
230 if((fmt2
=AllocVec(strlen(fmt
)+100,0))!=0) {
232 RawDoFmt("%s",args
,(void (*)())"\x16\xC0\x4E\x75",fmt2
);
235 struct EasyStruct es
;
236 ULONG
*args
=(ULONG
*)&gads
;
240 es
.es_StructSize
=sizeof(struct EasyStruct
);
242 es
.es_Title
="SFScheck request";
243 es
.es_TextFormat
=fmt2
;
244 es
.es_GadgetFormat
=gads
;
246 gadget
=EasyRequestArgs(0,&es
,0,args
);
257 void starttimeout(void) {
258 /* Called by deviceio.o each time there is a physical
259 disk access. You can use this to start a timer and
260 call motoroff() when the disk hasn't been accessed
261 for a specific amount of time (SFS uses 1 second).
263 SFScheck doesn't use this function. */
268 BOOL
checkchecksum(void *buffer
) {
269 if(CALCCHECKSUM(bytes_block
, buffer
)==0) {
276 ULONG
calculatechecksum(void *buffer
) {
277 ULONG oldchecksum
,checksum
;
279 struct fsBlockHeader
*bh
=(struct fsBlockHeader
*)buffer
;
281 oldchecksum
=bh
->checksum
;
282 bh
->checksum
=0; /* Important! */
283 checksum
=-CALCCHECKSUM(bytes_block
, (ULONG
*)buffer
);
284 bh
->checksum
=oldchecksum
;
289 void setchecksum(void *buffer
) {
290 struct fsBlockHeader
*bh
=(struct fsBlockHeader
*)buffer
;
292 bh
->checksum
=0; /* Important! */
293 bh
->checksum
=-CALCCHECKSUM(bytes_block
, (ULONG
*)buffer
);