3 Copyright (C) 2004 John Coffman.
6 Licensed under the terms contained in the file 'COPYING' in the LILO
12 #include "../src/bdata.h"
14 #define DISK_VERSION "3.0"
17 #define putch bios_putc
18 #define getch bios_getc
19 #define printf cprintf
23 #define putch(c) fputc((c),stdout)
38 #define SECTOR_SIZE 512
41 #define CL_MAGIC_ADDR 0x20
42 #define CL_MAGIC 0xa33f
43 #define CL_OFFSET 0x22
46 typedef unsigned char byte;
47 typedef unsigned short word;
48 typedef unsigned long dword;
50 extern union REGS __argr;
51 extern struct SREGS __argseg;
56 int num_hd = BD_MAX_HARD;
63 byte sector[SECTOR_SIZE];
64 word wsector[SECTOR_SIZE/2];
65 dword dsector[SECTOR_SIZE/4];
69 unsigned long linear(void *ptr)
72 return ((unsigned long)sreg.ds<<4) + (unsigned int)ptr;
83 int86(0x10, ®, ®);
85 int86(0x10, ®, ®);
90 int86(0x10, ®, ®);
94 void bios_putc(char c)
100 do bios_putc(' '); while(col&7);
102 case '\n': bios_putc0('\r');
108 if (c>=' ' && c<0177) col++;
114 void sizeit(unsigned long sectors)
116 static char suf[] = "KMGT";
120 /* print disk size in K,M,G,T */
123 if (sectors <= 999) {
124 printf("%ld%c", sectors, *cp);
128 while (sectors > 999999) {
132 if (sectors > 2999) {
136 sectors += 5; /* round decimal part */
138 fract = sectors % 100;
140 printf("%ld.%02d%c", sectors, fract, *cp);
144 void banner(char *version)
147 ">>>> Disk Maintenance Tools <<<<\n\n\n"
148 "Version %s, Copyright (C) 2004 John Coffman <johninsd@san.rr.com>\n"
149 "Portions Copyright (C) 1996-2001 Robert de Bath, used with permission\n"
150 "Re-use and redistribution rights set forth in the file \"COPYING\".\n\n",
168 int outb(int port, int data)
181 printf("%s\n", i?"yes":"no");
185 void decimal(unsigned long value)
189 for (i=0; i<4; i++) {
193 if (v[3]) printf("%d,%03d,%03d,%03d", v[3], v[2], v[1], v[0]);
194 else if (v[2]) printf("%d,%03d,%03d", v[2], v[1], v[0]);
195 else if (v[1]) printf("%d,%03d", v[1], v[0]);
196 else printf("%d", v[0]);
200 void print_regs(union REGS *reg) {
201 printf("AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x\n",
202 reg->x.ax, reg->x.bx, reg->x.cx, reg->x.dx, reg->x.si, reg->x.di);
206 void print_sregs(struct SREGS *sreg) {
207 printf("DS=%04x ES=%04x CS=%04x SS=%04x\n",
208 sreg->ds, sreg->es, sreg->cs, sreg->ss);
217 return (__argseg.es+0x10 == __argseg.cs);
225 /* Must be standalone */
226 printf("\n\n\nHit <Enter> to continue, <^C> to quit ...");
229 if (ch==CTRL_C) exit(0);
231 if (ch != CR) printf(" %o", ch);
240 /* dirty hack for DELL Dimension 4300 computers */
249 sreg.es = sreg.ds; /* as a general rule */
250 memset(®,rval,sizeof(reg));
251 memset(&oreg,rval,sizeof(oreg));
258 int peekw_es(int addr)
264 tem.ch[0] = __peek_es(addr);
265 tem.ch[1] = __peek_es(addr+1);
270 static void get_cmdline(char *cp)
275 __set_es(__argseg.ds);
276 if (peekw_es(CL_MAGIC_ADDR) == CL_MAGIC) {
277 addr = peekw_es(CL_OFFSET);
279 ch = __peek_es(addr++);
280 } while (ch && ch != '=');
282 *cp++ = ch = __peek_es(addr++);
289 int num_hard_disks(void)
294 int86(0x13, ®, &oreg);
295 return oreg.x.cflag ? 0 : (int)oreg.h.dl;
299 int disk_rw0(int bios, int rw, void *buffer)
304 while (err && errcnt) {
306 reg.h.ah = 2 + (rw & !DEBUG);
308 reg.x.cx = 1; /* sector=0 is sect=1, hd=0, cyl=0 */
311 reg.x.bx = (word)buffer;
312 /* ES is set == DS */
313 int86x(0x13, ®, &oreg, &sreg);
315 if ((err = (oreg.x.cflag || oreg.h.ah))) {
318 if (bios & 0x80) reg.h.ah = 0x0D;
319 int86(0x13, ®, &oreg);
322 } /* while (err && errcnt) */
324 printf("Disk error on 0x%02x, AH = 0x%02x\n", bios, code);
330 void disk_data(int bios)
332 if (!disk_rw0(bios, RD, buffer.x.sector)) {
333 printf(" %02x %08lx\n", bios, buffer.x.dsector[110]);
343 video_fix(); /* for Dumb DELL computers */
345 #if DEBUG>=1 && __MSDOS__==0
346 printf("Beginning of '___cstartup'\n");
348 printf("DS=%04x ES=%04x CS=%04x SS=%04x SP=%04x BP=%04x\n",
349 __argseg.ds, __argseg.es, __argseg.cs, __argseg.ss,
350 __argr.x.flags, __argr.x.cflag);
353 printf("\nBeginning of '_main'\n");
356 banner(DISK_VERSION);
358 printf("Command line: '%s' time=%ld\n", cp, time(NULL));
359 num_hd = num_hard_disks();
360 printf("The BIOS reports %d hard disks.\n", num_hd);
361 for (i=0; i<num_hd; i++) disk_data(0x80+i);