bf775d00984399b2131bac1ae7d3c38cf68d6e31
2 * (C) Copyright 2002, Brian Knittel.
3 * You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
4 * RISK basis, there is no warranty of fitness for any purpose, and the rest of the
5 * usual yada-yada. Please keep this notice and the copyright in any distributions
8 * This is not a supported product, but I welcome bug reports and fixes.
9 * Mail to sim@ibm1130.org
12 // checkdisk - validates and optionally dumps an IBM1130 DMS2 disk image file
15 // checkdisk [-f] [-d cyl.sec|abssec] [-n count] filename
19 // report any misnumbered sectors in file.dsk
21 // checkdisk -f file.dsk
22 // report and fix any misnumbered sectors
24 // checkdisk -d 198.0 file.dsk
25 // dump cylinder 198 sector 0
27 // checkdisk -d 0 file.dsk
28 // dump absolute sector 0
30 // checkdisk -d 198.0 -n 4 file.dsk
31 // dump 4 sectors starting at m.n
32 // -----------------------------------------------------------------------------------------
41 long filelength (int fno
);
42 # include <sys/types.h>
43 # include <sys/stat.h>
52 #define DSK_NUMWD 321 /* words/sector */
53 #define DSK_NUMSC 4 /* sectors/surface */
54 #define DSK_NUMSF 2 /* surfaces/cylinder */
55 #define DSK_NUMCY 203 /* cylinders/drive */
56 #define DSK_NUMDR 5 /* drives/controller */
57 #define DSK_SIZE (DSK_NUMCY * DSK_NUMSF * DSK_NUMSC * DSK_NUMWD) /* words/drive */
59 char *usestr
= "Usage: checkdisk [-f] [-d cyl.sec|abssec] [-n count] diskfile";
60 char *baddisk
= "Cannot fix this";
62 void bail (char *msg
);
63 char *lowcase (char *str
);
65 int main (int argc
, char **argv
)
68 char *fname
= NULL
, *arg
, *argval
;
69 int i
, j
, cyl
, sec
, pos
, asec
, retry
, nbad
= 0, nfixed
= 0, nline
;
70 BOOL fixit
= FALSE
, dump
= FALSE
;
72 unsigned short wd
, buf
[DSK_NUMWD
];
74 for (i
= 1; i
< argc
;) {
92 if (strchr(argval
, '.') != NULL
) {
93 if (sscanf(argval
, "%d.%d", &cyl
, &sec
) != 2)
96 dsec
= cyl
*(DSK_NUMSF
*DSK_NUMSC
) + sec
;
98 else if (sscanf(argval
, "%d", &dsec
) != 1)
101 if (dsec
< 0 || dsec
>= (DSK_NUMCY
*DSK_NUMSF
*DSK_NUMSC
))
102 bail("No such sector");
111 if (sscanf(argval
, "%d", &nsec
) != 1)
124 else if (fname
== NULL
)
133 if ((fp
= fopen(fname
, "rb+")) == NULL
) {
138 if (filelength(fileno(fp
)) != 2*DSK_SIZE
) {
139 fprintf(stderr
, "File is wrong length, expected %d\n", DSK_SIZE
);
143 for (cyl
= 0; cyl
< DSK_NUMCY
; cyl
++) {
144 for (sec
= 0; sec
< (DSK_NUMSF
*DSK_NUMSC
); sec
++) {
147 asec
= cyl
*(DSK_NUMSF
*DSK_NUMSC
) + sec
;
148 pos
= asec
*2*DSK_NUMWD
;
150 if (fseek(fp
, pos
, SEEK_SET
) != 0) {
151 fprintf(stderr
, "Error seeking to pos %x\n", pos
);
155 if (fxread(&wd
, sizeof(wd
), 1, fp
) != 1) {
156 fprintf(stderr
, "Error reading word at abs sec %x, cyl %x, sec %x at offset %x\n", asec
, cyl
, sec
, pos
);
161 fprintf(stderr
, "Bad sector #%x at abs sec %x, cyl %x, sec %x at offset %x\n", wd
, asec
, cyl
, sec
, pos
);
165 if (fseek(fp
, pos
, SEEK_SET
) != 0) {
166 fprintf(stderr
, "Error seeking to pos %x\n", pos
);
170 if (fxwrite(&asec
, sizeof(wd
), 1, fp
) != 1) {
171 fprintf(stderr
, "Error writing sector # to abs sec %x, cyl %x, sec %x at offset %x\n", asec
, cyl
, sec
, pos
);
181 fprintf(stderr
, "Failed after retry\n");
189 printf("%d bad sector mark%s %s\n", nbad
, (nbad
== 1) ? "" : "s", fixit
? "fixed" : "found");
191 printf("All sector marks OK\n");
196 pos
= dsec
*2*DSK_NUMWD
;
197 if (fseek(fp
, pos
, SEEK_SET
) != 0) {
198 fprintf(stderr
, "Error seeking to pos %x\n", pos
);
202 for (i
= 0; i
< nsec
; i
++) {
203 cyl
= dsec
/ (DSK_NUMSF
*DSK_NUMSC
);
204 sec
= dsec
- cyl
*(DSK_NUMSF
*DSK_NUMSC
);
206 if (fxread(&buf
, sizeof(buf
[0]), DSK_NUMWD
, fp
) != DSK_NUMWD
) {
207 fprintf(stderr
, "Error reading abs sec %x, cyl %x, sec %x at offset %x\n", dsec
, cyl
, sec
, pos
);
211 printf("\nSector %d.%d - %d - /%04x label %04x\n", cyl
, sec
, dsec
, dsec
, buf
[0]);
212 for (nline
= 0, j
= 1; j
< DSK_NUMWD
; j
++) {
213 printf("%04x", buf
[j
]);
228 void bail (char *msg
)
230 fprintf(stderr
, "%s\n", msg
);
234 /* ------------------------------------------------------------------------
235 * lowcase - force a string to lower case (ASCII)
236 * ------------------------------------------------------------------------ */
238 char *lowcase (char *str
)
242 for (s
= str
; *s
; s
++) {
243 if (*s
>= 'A' && *s
<= 'Z')
252 long filelength (int fno
)
256 if (fstat(fno
, &sb
) != 0)
259 return (long) sb
.st_size
;