|
25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more... |
Home Projects Up Sitemap Search Blog Forum+Chat About Us Privacy Terms of Use Feedback FAQ Images Services Ads Donate Humor |
|
|
Read absolute disk sectorsReadSect.cpp reads absolute disk sectors using Borland C++ 4.0 DOS-only functions. The functions rely on MSDOS system calls, so this program can only read disk formats that MSDOS recognizes and supports. Click here to download readsect.zip (17 KB). The zip file contains the same items that are listed on this web page:
The items in this project were part of an attempt to use a DOS 6.0 / Windows 3.1 computer to rescue data from 5 1/4" floppy disks from a Heathkit H-100 computer that were in 96 TPI (Track Per Inch) 640KB and 720KB formats. The attempt was unsuccessful. If you are working on something for which you need the information in this project, you have my sympathy. |
|
/* readsect.cpp 12-11-99
Copyright (C)1999 Steven Whitney.
Published under GNU GPL (General Public License) Version 2, with ABSOLUTELY NO WARRANTY.
Initially published by http://25yearsofprogramming.com.
Reads absolute disk sectors using Borland C++ 4.0 MSDOS DOS-only functions.
Although it only reads, you should nonetheless study and make sure you understand what this
program does before you run it.
This program was part of an unsuccessful attempt to use a DOS 6.0 / Windows 3.1 computer to
rescue data from 5" floppy disks from a Heathkit H-100 computer that were in
96 tpi (track-per-inch), 640KB and 720KB formats.
Because these Borland functions use DOS calls, they still rely on the parameters in the DOS
disk tables. They cannot bypass them. I also tried manually modifying the disk tables,
but no combination of parameters worked. There may be tasks for which this program is useful,
but getting data from disks that are not in one of the standard, currently supported,
MSDOS disk formats is not one of them.
------
TO DO:
"Sector Not Found" errors: the sector header includes track/side/sectorno.
(with sectorno applying only to the current track)
you're searching for an exact match for all 3, and if your translation
routine (driver?) calculates the wrong combination and passes it
to the controller for the search, the sector won't be found, even if the sector
itself can be read ok.
8/13/05
If necessary, copy this to a new project and modify it for use on the P5-90 hard disk.
On a hard disk, a cylinder is the same as a track. All the heads are always simultaneously
on the same track of their respective platters; they move together.
------
NOTES:
*/
#include <bios.h>
#include <dos.h>
#pragma hdrstop
#include "c:\bcs\my.h"
#include "c:\bcs\mylib.cpp"
//////////////////////////////////////////////////////////////////////////////
// global data
//----------------------------------------------------------------------------
BOOL showsectordata;
char buffer[3 * 512]; // add 4 bytes for long read (516)
//----------------------------------------------------------------------------
// translate to viewable chars that won't mess up screen.
uchar MakePrintable(int ch)
{
ch &= 0x7F; // strip parity
if((ch < 32) || (ch == 127))
return('.'); // show control codes as dots
return(ch);
} //MakePrintable
//----------------------------------------------------------------------------
void diskstatus()
{
// 15 79 2 1 // normal values reported for 5" drive
// try setting drive B: parms
// what, and how passed? in buffer? note desc says "drive PAIR" parms.
// buffer[0] = 15; buffer[1] = 79; buffer[2] = 2; buffer[3] = 1;
// int result = biosdisk(9, 1, 1, 79, 9, 1, buffer);
// cout << "Result code: 0x" << hex << result << dec << endl;
// cout << endl;
//
// report drive characteristics
// B: is reported as 15 sectors even after drivparm sets it to 9 in config.sys.
for(int drive = 0 ; drive < 2 ; drive++)
{
int result = biosdisk(8, drive, 0, 0, 1, 1, buffer);
cout << "Result code: 0x" << hex << result << dec << endl;
cout << "Drive " << (char)(drive + 'A') << ": characteristics: " << endl;
for(int i = 0 ; i < 4 ; i++)
cout << hex << "0x" << (uint)buffer[i] << dec << " ";
cout << endl;
for(i = 0 ; i < 4 ; i++)
cout << " " << (uint)buffer[i] << " ";
cout << endl;
}
cout << endl;
} //diskstatus
//----------------------------------------------------------------------------
// returns user keypress, which can be ESC to abort current process
int showsector()
{
for(int i = 0 ; i < 512; i++)
cout << MakePrintable(buffer[i]);
cout << endl;
return(presskey());
} //showsector
//----------------------------------------------------------------------------
// it cannot read an H100 96tpi disk beyond sector 9. (track 0 only)
int usebiosdisk()
{
int ch = 0;
cout << "Attempting to read from drive B: using BIOSDISK" << endl;
for(int track = 0 ; track < 80 ; track++) // numbering starts at 0
{
for(int sector = 1 ; sector < 10 ; sector++) // numbering starts at 1
{
for(int head = 0 ; head < 2 ; head++)
{
int drive = 1; // 1 = B:
int result = biosdisk(2, drive, head, track, sector, 1, buffer);
cout << "Track " << track << ", Sector " << sector << ", Head " << head << ": ";
if(result == 0)
{
cout << "OK!" << endl;
}
else
{
cout << "Failed: 0x" << hex << result << dec << endl;
}
if(showsectordata)
ch = showsector();
if(ch == ESC)
break;
}
if(ch == ESC)
break;
}
if(ch == ESC)
break;
if(kbhit())
{
getch();
break;
}
}
// hard controller reset, just in case? (untested, might reset computer? or crash?)
// result = biosdisk(0, 1, 0, 0, 1, 1, buffer);
return(1);
} //usebiosdisk
//----------------------------------------------------------------------------
// H100 disk using normal drivparms: no.
// H100 disk using modified drivparms: read 18 sectors, then errors,
// then some more sectors, then all errors thereafter.
// absread changes data at 70:34e to 54e, biosdisk doesn't.
int useabsread()
{
int ch = 0;
cout << "Attempting to read from drive B: using ABSREAD" << endl;
for(long sector = 0 ; sector < 1440 ; sector++) // numbering starts at 0
{
int drive = 1; // 1 = B:
int result = absread(drive, 1, sector, buffer);
// cout << "Track " << track << ", Sector " << sector << ", Head " << head << ": ";
cout << "Sector " << sector << ": ";
if(result == 0)
{
cout << "OK!" << endl;
}
else
{
cout << "Failed: 0x" << hex << errno << dec << endl;
}
if(showsectordata)
ch = showsector();
if(kbhit() || (ch == ESC))
break;
}
return(1);
} //useabsread
//----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////
int main()
{
string::set_case_sensitive(0);
string::set_paranoid_check(1);
clrscr();
cout << setiosflags(ios::uppercase);
cout << "Insert disk in drive B:" << endl;
presskey();
while(1)
{
int choice;
do
{
cout << endl;
cout << "-----------------------------------------------" << endl;
cout << "0 Exit" << endl;
cout << "1 Disk status report" << endl;
cout << "2 Use BIOSDISK to read B:" << endl;
cout << "3 Use ABSREAD to read B:" << endl;
cout << "4 DIR B:" << endl;
cout << "5 B: FAT ID and structure info" << endl;
cout << endl << "Enter choice: ";
cin >> choice;
cout << endl;
}
while((choice < 0) || (choice > 5));
switch(choice)
{
case 0:
return(0);
case 1:
diskstatus();
break;
case 2:
showsectordata = yesno("Show sector data");
cout << "Press ESC to quit" << endl;
usebiosdisk();
break;
case 3:
showsectordata = yesno("Show sector data");
cout << "Press ESC to quit" << endl;
useabsread();
break;
case 4:
system("dir b:");
break;
case 5:
{
// getfat() uses DOS function 1C (not in ZDOS).
// it reads FAT ID from disk EACH CALL (no disk change test).
// the fn call 1C seems to return the various info in registers upon return,
// and getfat() transfers it into the struct.
struct fatinfo diskinfo = {0,0,0,0};
getfat(2, &diskinfo);
cout << " FAT ID byte is: " << hex << (uint)diskinfo.fi_fatid << dec << endl;
cout << " bytes per sector: " << (uint)diskinfo.fi_bysec << endl;
cout << " sectors per cluster: " << (uint)diskinfo.fi_sclus << endl;
cout << " number of clusters: " << (uint)diskinfo.fi_nclus << endl;
break;
}
} // switch
} // end while(1)
} // end main
11-15-99 Debug. This is everything readable from an H100 96tpi disk.
Boot Loader:
Starts with disk format table! See zdos\DEFFMT.ASM
MS-defined entries:
|start of table
|Version of table
| |Sector size of disk(in bytes)
| |cluster factor
| |reserved sector count
| |FAT count
| |DIR entry count
| |Physical sector count (5A0)
After here, Zenith-defined entries:
| |Shift count (Log2 SECS)
jmp +1f | |Sectors/track
0000 EB 1F 00 02 00 02 04 01-00 02 90 00 A0 05 09 09 ................
|Data area sector number
|Shift count (Log2 cluster size)
|Directory area sector number
|Flag byte (DSK_FLAG)
|Select byte (DSK_SEL)
|Port number of controller
|Date and time?
0010 0E 00 02 05 00 01 08 B0-00 17 15 12 03 2E 62 00 ..............b.
|code starts
0020 00 0E 1F B8 00 14 8E C0-B9 00 3C BE 00 04 8B FE ..........<.....
0030 FC F3 A4 EA 38 04 00 14-8C C8 8E D8 33 DB 8E C3 ....8.......3...
0040 26 8E 06 FE 03 26 8A 1E-09 00 89 1E 17 04 26 8A &....&........&.
0050 1E 5A 00 08 1E 16 04 8E-C0 B0 08 E6 FC 8B 1E 13 .Z..............
0060 04 8A 0E 0E 04 D3 E3 F6-06 16 04 04 75 13 80 3E ............u..>
0070 12 04 02 7D 0C E8 56 01-A8 08 74 05 80 0E 15 04 ...}..V...t.....
0080 0C B9 0B 00 8D B7 00 04-BF EB 04 F3 A6 75 3E 8B .............u>.
0090 87 1A 04 2D 02 00 8A 0E-12 04 D3 E0 03 06 10 04 ...-............
00A0 A3 0F 05 8B 87 1C 04 8B-0E 04 04 49 03 C1 8A 0E ...........I....
00B0 0E 04 D3 E8 A3 11 05 BB-0E 05 B0 02 E8 58 00 72 .............X.r
00C0 13 8C C8 05 40 00 8E D8-EA 00 00 40 00 BB F6 04 ....@......@....
00D0 B5 0D EB 05 BB 01 05 B5-0D 8A 07 53 51 9A 19 00 ...........SQ...
00E0 01 FE 59 5B 43 FE CD 75-F0 EB FE 49 4F 20 20 20 ..Y[C..u...IO
00F0 20 20 20 53 59 53 0D 0A-4E 6F 20 53 79 73 74 65 SYS..No Syste
0100 6D 0D 0A 49 2F 4F 20 65-72 72 6F 72 0D 0A 00 00 m..I/O error....
0110 00 00 00 00 00 40 00 26-8B 47 01 A3 F8 05 A1 F8 .....@.&.G......
0120 05 F6 36 0F 04 FE C4 32-D2 F6 06 15 04 01 74 06 ..6....2......t.
0130 D0 E8 73 02 B2 02 88 16-F7 05 8A 2E 20 04 A2 20 ..s......... ..
0140 04 E8 AA 00 B0 1F E8 77-00 F6 06 15 04 04 74 10 .......w......t.
0150 A0 20 04 E8 98 00 8A C5-E8 89 00 B0 1F E8 60 00 . ............`.
0160 E8 54 00 8A C4 E8 81 00-A0 16 04 0C 40 E8 6B 00 .T..........@.k.
0170 8B 0E 04 04 06 26 C4 7F-05 FC B0 88 0A 06 F7 05 .....&..........
0180 9C FA 8B 16 17 04 83 C2-03 52 8B 16 17 04 EE 5A .........R.....Z
0190 EC AA E2 FC A0 16 04 E8-41 00 E8 26 00 9D 07 84 ........A..&....
01A0 C0 74 02 F9 C3 FF 06 F8-05 26 89 7F 05 26 FF 4F .t.......&...&.O
01B0 03 74 03 E9 68 FF C3 51-B9 A0 0F 49 75 FD 59 C3 .t..h..Q...Iu.Y.
01C0 E8 1D 00 E8 08 00 A8 01-74 F9 E8 06 00 C3 BA 05 ........t.......
01D0 00 EB 02 33 D2 03 16 17-04 EC C3 BA 04 00 EB 11 ...3............
01E0 33 D2 EB 0D BA 01 00 EB-08 BA 02 00 EB 03 BA 03 3...............
01F0 00 03 16 17 04 EE C3 00-00 00 56 46 3A 07 73 08 ..........VF:.s.
FAT1
0200 F9 FF FF 03 40 00 05 60-00 07 80 00 09 F0 FF 0B ....@..`........
0210 C0 00 0D E0 00 0F 00 01-11 20 01 FF 4F 01 15 60 ......... ..O..`
...all H100 disks (48 and 96) seem to have this 'N' section
04B0 E5 E5 E5 E5 E5 E5 E5 E5-E5 E5 E5 F7 4E 4E 4E 4E ............NNNN
04C0 4E 4E 4E 4E 4E 4E 4E 4E-4E 4E 4E 4E 4E 4E 4E 4E NNNNNNNNNNNNNNNN
05F0 E5 E5 E5 E5 E5 E5 E5 E5-E5 E5 E5 E5 E5 E5 E5 E5 ................
FAT2 same
0600 F9 FF FF 03 40 00 05 60-00 07 80 00 09 F0 FF 0B ....@..`........
09F0 E5 E5 E5 E5 E5 E5 E5 E5-E5 E5 E5 E5 E5 E5 E5 E5 ................
DIR
0A00 49 4F 20 20 20 20 20 20-53 59 53 27 00 00 00 00 IO SYS'....
0A10 00 00 00 00 00 00 3D 4E-34 0B 02 00 01 3A 00 00 ......=N4....:..
0A20 4D 53 44 4F 53 20 20 20-53 59 53 27 00 00 00 00 MSDOS SYS'....
0A30 00 00 00 00 00 00 38 6B-2A 09 0A 00 AF 42 00 00 ......8k*....B..
11F0 E5 E5 E5 E5 E5 E5 E5 E5-E5 E5 E5 E5 E5 E5 E5 E5 ................
END OF 9 SECTORS
1200 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
CHKDSK on an H100 disk:
D:\TEMP>chkdsk b:
Errors found, F parameter not specified
Corrections will not be written to disk
1,515 lost allocation units found in 1,302 chains.
775,680 bytes disk space would be freed
1,213,952 bytes total disk space
438,272 bytes available on disk
512 bytes in each allocation unit
2,371 total allocation units on disk
856 available allocation units on disk
I tried Scandisk /checkonly. It reported 2nd FAT out of date, and disk read
error at directory entry #144. It said FAT #1 was ok, and found no problems
with the directory structure.
//----------------------------------------------------------------------------
Boot loader from RAMDRIVE (D:):
Look for references to its format OUTSIDE the FAT ID byte:
|Sector size of disk(in bytes)
|cluster factor
|reserved sector count
|text...................| | |
0000 EB 1D 90 52 44 56 20 31-2E 32 30 00 02 02 01 00 ...RDV 1.20.....
|FAT count
|DIR entry count
|Physical sector count (5A0)
|new entries? (not provided for in DOS1)
|
|Sectors/track
| |=16 |=4096|id|
0010 01 10 00 00 10 F8 06 00-01 00 01 00 00 00 08 EB ................
0020 FE 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 .AAAAAAAAAAAAAAA
This is the FAT1 (there IS no FAT2). Note the extra FFs in header.
ramdrive gets the FAT of a hard disk.
0200 F8 FF FF FF FF FF 05 60-00 07 80 00 09 A0 00 0B .......`........
0210 C0 00 0D E0 00 0F 00 01-11 20 01 13 40 01 15 60 ......... ..@..`
//----------------------------------------------------------------------------
Boot loader from 360k 5" disk:
|Sector size of disk(in bytes)
|cluster factor
|reserved sector count
|jmp +3C |text...................| | |
0000 EB 3C 90 4D 53 44 4F 53-35 2E 30 00 02 02 01 00 .<.MSDOS5.0.....
|FAT count
|DIR entry count
|Physical sector count (5A0)
|new entries? (not provided for in DOS1)
|
|Sectors/track
| |=112 |=720 |id|
0010 02 70 00 D0 02 FD 02 00-09 00 02 00 00 00 00 00 .p..............
0020 00 00 00 00 00 00 29 E4-09 1F 2B 4E 4F 20 4E 41 ......)...+NO NA
0030 4D 45 20 20 20 20 46 41-54 31 32 20 20 20 FA 33 ME FAT12 .3
0040 C0 8E D0 BC 00 7C 16 07-BB 78 00 36 C5 37 1E 56 .....|...x.6.7.V
FAT1 of newly formatted 5"
0200 FD FF FF 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
FAT2 at 600 = same.
//----------------------------------------------------------------------------
Boot loader from freshly formatted 1.2M 5" disk:
0000 EB 3C 90 4D 53 44 4F 53-35 2E 30 00 02 01 01 00 .<.MSDOS5.0.....
0010 02 E0 00 60 09 F9 07 00-0F 00 02 00 00 00 00 00 ...`............
0020 00 00 00 00 00 00 29 49-41 05 09 4E 4F 20 4E 41 ......)IA..NO NA
0030 4D 45 20 20 20 20 46 41-54 31 36 20 20 20 FA 33 ME FAT16 .3
FAT:
0200 F9 FF FF 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
//----------------------------------------------------------------------------
Boot loader from an H100 48tpi disk:
chkdsk doesn't report a Vol. Serial Number for this disk.
See DOS2 chkdsk: it reports a creation date, which may be encoded here
somewhere.
0000 EB 1F 00 02 00 02 02 01-00 02 70 00 D0 02 09 09 ..........p.....
0010 0C 00 01 05 00 01 18 B0-00 33 0C 04 29 21 54 00 .........3..)!T.
0020 00 0E 1F B8 00 14 8E C0-B9 00 3C BE 00 04 8B FE ..........<.....
//----------------------------------------------------------------------------
Boot loader from Hard disk C:
0000 EB 3C 90 4D 53 44 4F 53-35 2E 30 00 02 40 01 00 .<.MSDOS5.0..@..
0010 02 00 02 00 00 F8 81 00-3F 00 40 00 3F 00 00 00 ........?.@.?...
0020 C1 3C 20 00 80 00 29 02-1E 02 16 4E 4F 20 4E 41 .< ...)....NO NA
0030 4D 45 20 20 20 20 46 41-54 31 36 20 20 20 FA 33 ME FAT16 .3
//----------------------------------------------------------------------------
The web page at http://home.cfl.rr.com/eaa/FloppyDisks.htm has a table similar to this one with some additional information you might find useful.
|
|
|
|
|
|