home *** CD-ROM | disk | FTP | other *** search
- { This program demonstrates some additional functions which }
- { should be considered if a requirement is for analysis of }
- { diskette data on a direct basis. It includes work initially }
- { done by Bela Lubkin of Borland and has been extended to allow }
- { direct access to diskette data at a Head, Track, and Sector }
- { level of addressing. This is a requirement when working with }
- { non-DOS, and DOS's with different logical configurations (i.e.}
- { DOS 1.1 doesn't know of sector 9, DOS 2.1 of sector 10). What}
- { makes this possible is through direct diskette i/o using }
- { interrupt 13h as referenced in the system bios section of the }
- { IBM Technical Reference Manual. Al Edlund }
-
- PROGRAM DISKREAD;
- const w1x1 = 1;
- w1x2 = 64;
- w1y1 = 1;
- w1y2 = 25;
- w2x1 = 65;
- w2x2 = 80;
- w2y1 = 5;
- w2y2 = 20;
-
- type regpack = record
- ax,bx,cx,dx,bp,di,si,ds,es,flags : integer;
- end;
- Str = String[4];
-
-
- var recpack : regpack;
- ah,al,ch,cl,dh,dl : byte;
- DiskStatus : integer;
- drivenumber : integer;
- headnumber : integer;
- tracknumber : integer;
- sectornumber : integer;
- DR,LS,Result,C : integer;
- k,x,y : integer;
- max_sector_count,mode : integer;
- max_count,moden : integer;
- W,selch : Char;
- V : Str;
- Changed : Boolean;
- t248,t249,t252 : boolean;
- t253,t254,t255 : boolean;
- errmsg : string[14];
- disktype : string[14];
- DiskRecord : array[0..511] of byte;
- altered_byte : array[0..511] of boolean;
-
-
- Procedure Analyze_Status(errcode : integer);
- begin
- case errcode of
- 0 : errmsg := 'Clean Complete';
- 1 : errmsg := 'Bad Command ';
- 2 : errmsg := 'No Addr Mark ';
- 3 : errmsg := 'Write Protect ';
- 4 : errmsg := 'No Sector ';
- 8 : errmsg := 'DMA Overrun ';
- 9 : errmsg := 'DMA 64K Error ';
- 16 : errmsg := 'Data CRC Error';
- 32 : errmsg := 'Disk Ctrlr Err';
- 64 : errmsg := 'Seek Failure ';
- 128 : errmsg := 'Disk Time Out ';
- end;
- end;
-
- Function __ReadWriteSectors(Var Buffer;
- Drive, NumberSectors, LogicalSector: Integer;
- WriteFlag: Byte): Integer;
- Var Result: Integer;
- Begin
- Result := 0;
- Inline($8A/$86/ Drive / { MOV AL,[BP+Drive] }
- $8B/$8E/ NumberSectors / { MOV CX,[BP+NumberSectors] }
- $8B/$96/ LogicalSector / { MOV DX,[BP+LogicalSector] }
- $55/ { PUSH BP }
- $1E/ { PUSH DS }
- $C5/$9E/ Buffer / { LDS BX,[BP+Buffer] }
- $80/$BE/ WriteFlag /$01/ { CMP BYTE PTR [BP+WriteFlag],1 }
- $74/$04/ { JE Write }
- $CD/$25/ { INT 25H }
- $EB/$02/ { JMP WrapUp }
- $CD/$26/ {Write: INT 26H }
- $5B/ {WrapUp:POP BX ;Dispose of flags }
- $1F/ { POP DS }
- $5D/ { POP BP }
- $73/$04/ { JNB Ok }
- $89/$86/ Result { MOV [BP+Result],AX }
- ); {Ok: }
- __ReadWriteSectors := Result;
- End;
-
- Function ReadSectors(Var Buffer;
- Drive, NumberSectors, LogicalSector: Integer): Integer;
- Begin
- ReadSectors:=
- __ReadWriteSectors(Buffer,Drive,NumberSectors,LogicalSector,0);
- End;
-
- Function WriteSectors(Var Buffer;
- Drive, NumberSectors, LogicalSector: Integer): Integer;
- Begin
- WriteSectors:=
- __ReadWriteSectors(Buffer,Drive,NumberSectors,LogicalSector,1);
- End;
-
-
- Procedure Read_Disk_Data(drivenumber,headnumber,tracknumber,sectornumber:integer);
- var sectorcount : integer;
-
- begin
- SectorCount := 1;
- ah := 2; {read command}
- al := SectorCount;
- ch := TrackNumber;
- cl := SectorNumber;
- dh := HeadNumber;
- dl := DriveNumber;
- with recpack do begin
- ax := ah shl 8 + al;
- cx := ch shl 8 + cl;
- dx := dh shl 8 + dl;
- es := seg(DiskRecord);
- bx := ofs(DiskRecord);
- end;
- intr($13,recpack);
- end;
-
- Procedure Write_Disk_Data(drivenumber,headnumber,tracknumber,sectornumber:integer);
- var changetrack : boolean;
- sectorcount : integer;
-
- begin
- SectorCount := 1;
- ah := 3; {write command}
- al := SectorCount;
- ch := TrackNumber;
- cl := SectorNumber;
- dh := HeadNumber;
- dl := DriveNumber;
- with recpack do begin
- ax := ah shl 8 + al;
- cx := ch shl 8 + cl;
- dx := dh shl 8 + dl;
- es := seg(DiskRecord);
- bx := ofs(DiskRecord);
- end;
- intr($13,recpack);
- end;
-
-
- Procedure Read_Disk_Status;
- begin
- diskstatus := 0;
- ah := 1; {read status command}
- with recpack do begin
- ax := ah shl 8 + al;
- end;
- intr($13,recpack);
- with recpack do begin
- ah := ax shr 8;
- DiskStatus := ah;
- end;
- Analyze_Status(diskstatus);
- end;
-
- Procedure Disk_Reset;
- begin
- ah := 0; {reset disk command}
- with recpack do begin
- ax := ah shl 8 + al;
- end;
- intr($13,recpack);
- end;
-
- Function Int2Hex2(B: Byte): Str;
- Const H: Array [0..15] Of Char='0123456789ABCDEF';
- Begin
- Int2Hex2:=H[B Shr 4]+H[B And 15];
- End;
-
- Function Int2Hex4(I: Integer): Str;
- Const H: Array [0..15] Of Char='0123456789ABCDEF';
- Begin
- Int2Hex4:=H[I Shr 12]+H[(I Shr 8) And 15]+H[(I Shr 4) And 15]+H[I And 15];
- End;
-
- Function Hex2Int1(C: Char): Byte;
- Begin
- Case Upcase(C) Of
- '0'..'9': Hex2Int1:=Ord(C) And 15;
- 'A'..'F': Hex2Int1:=Ord(C) And 15+9;
- Else Hex2Int1:=0;
- End;
- End;
-
- Function Hex2Int4(S: Str; Default: Integer): Integer;
- Var I: Integer;
- Begin
- If S='' Then Hex2Int4:=Default
- Else
- Begin
- I:=0;
- While S<>'' Do
- Begin
- I:=I Shl 4 + Hex2Int1(S[1]);
- Delete(S,1,1);
- End;
- Hex2Int4:=I;
- End;
- End;
-
-
-
-
- Procedure ShowSector(Var S);
- Var Buffer : Array [0..31,0..15] Of Byte Absolute S;
- colarr : Array [0..31,0..15] of boolean absolute altered_byte;
- I,J : Integer;
- B : Byte;
-
- Begin
- window(w1x1,w1y1,w1x2,w1y2);
- clrscr;
- gotoxy(7,4);
- write(' 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF');
- gotoxy(1,5);
- textcolor(white);
- For I:=0 To 15 Do
- Begin
- Write(Int2Hex4(I Shl 4),'| ');
- For J:=0 To 15 Do
- Begin
- if colarr[i,j] = true then textcolor(yellow)
- else textcolor(white);
- Write(Int2Hex2(Buffer[I,J]));
- If J And 3 = 3 Then Write(' ');
- if j and 15 = 7 then write(' ');
- End;
- Write('| ');
- For J:=0 To 15 Do
- Begin
- B:=Buffer[I,J];
- If B<127 Then textcolor(blue)
- Else textcolor(cyan);
- B:=B And $7F;
- If B<32 Then B:=Ord('.');
- Write(Chr(B));
- End;
- textcolor(white);
- WriteLn;
- End;
- gotoxy(1,23); clreol;
- writeln('(CR) to continue');
- read(selch);
- gotoxy(1,5);
- For I:=16 To 31 Do
- Begin
- Write(Int2Hex4(I Shl 4),'| ');
- For J:=0 To 15 Do
- Begin
- if colarr[i,j] = true then textcolor(yellow)
- else textcolor(white);
- Write(Int2Hex2(Buffer[I,J]));
- If J And 3 = 3 Then Write(' ');
- if j and 15 = 7 then write(' ');
- End;
- Write('| ');
- For J:=0 To 15 Do
- Begin
- B:=Buffer[I,J];
- If B<127 Then textcolor(blue)
- Else textcolor(cyan);
- B:=B And $7F;
- If B<32 Then B:=Ord('.');
- Write(Chr(B));
- End;
- textcolor(white);
- WriteLn;
- End;
- gotoxy(1,23); clreol;
- window(w2x1 + 1, w2y1 + 1, w2x2 - 1, w2y2 - 1);
- writeln;
- End;
-
- Procedure Real_Read;
-
- begin
- clrscr;
- disk_reset;
- read_disk_status; {to clear the adapter}
- gotoxy(1,1);
- Writeln(' Real Mode');
- writeln;
- writeln(' DR HD TR SC');
- writeln(' ', drivenumber:2, ' ', headnumber:2, ' ',tracknumber:2, ' ',sectornumber:2);
- writeln;
- write(' Drive # = '); readln(drivenumber);
- write(' Head # = '); readln(headnumber);
- write(' Track # = '); readln(tracknumber);
- write(' Sector # = '); readln(sectornumber);
- read_disk_data(drivenumber,0,0,2);
- read_disk_status;
- case diskrecord[0] of
- 255 : disktype := 'DBLSIDED--8SEC';
- 254 : disktype := 'SNGSIDED--8SEC';
- 253 : disktype := 'DBLSIDED--9SEC';
- 252 : disktype := 'SNGSIDED--9SEC';
- 249 : disktype := 'DBLSIDED-15SEC';
- 248 : disktype := 'HARD DISK ';
- end;
- read_disk_data(drivenumber,headnumber,tracknumber,sectornumber);
- read_disk_status;
- if diskstatus = 0 then begin
- for k := 0 to 511 do begin
- altered_byte[k] := false;
- end;
- textcolor(green);
- gotoxy(1,w2y2 - w2y1 - 2);
- write(errmsg);
- textcolor(white);
- gotoxy(1,11);
- writeln(' Disktype =');
- write(disktype);
- showsector(diskrecord);
- clrscr;
- gotoxy(1,1);
- writeln(' Do you wish');
- write(' to alter this');
- writeln(' record (Y/N)');
- read(selch);
- If Upcase(selch)='Y' then begin
- repeat
- clrscr;
- gotoxy(1,1);
- Writeln(' Enter the ');
- writeln(' positon of');
- writeln(' the byte to');
- writeln(' change. ');
- write('( 0-1FF, CR to end): ');
- ReadLn(V);
- C:=Hex2Int4(V,-1);
- If (C >= 0) And (C < 511) Then begin
- clrscr;
- gotoxy(1,1);
- Writeln(' Enter new');
- writeln(' value [',Int2Hex2(diskrecord[C]),']: ');
- ReadLn(V);
- If Length(V) > 1 Then
- If V[1] In ['''','"'] Then diskrecord[C] := Ord(V[2])
- Else diskrecord[C] := Hex2Int4(V,diskrecord[C])
- Else diskrecord[C] := Hex2Int4(V,diskrecord[C]);
- Changed := True;
- if changed = true then altered_byte[c] := true;
- End
- Else C := -1;
- Until C = -1;
- showsector(diskrecord);
- If Changed then begin
- gotoxy(1,1); clrscr;
- Write(' Write changes');
- writeln(' back to real');
- writeln(' sector # ');
- writeln(' DR HD TR SC');
- writeln(' ', drivenumber:2, ' ', headnumber:2, ' ',tracknumber:2, ' ',sectornumber:2);
- writeln(' (Y/N)? ');
- Read(W);
- If Upcase(W)='Y' then begin
- Write_disk_data(drivenumber,headnumber,tracknumber,sectornumber);
- read_disk_status;
- if diskstatus = 0 then textcolor(green)
- else textcolor(20);
- gotoxy(1,w2y2 - w2y1 - 2);
- writeln(errmsg);
- textcolor(white);
- End; {end write back}
- end; {end test for changed}
- end; {end change record (y/n)}
- end; { good complete from read}
- if diskstatus <> 0 then begin
- window(w1x1,w1y1,w1x2,w1y2);
- clrscr;
- window(w2x1 + 1, w2y1 + 1, w2x2 - 1, w2y2 - 1);
- clrscr;
- textcolor(20);
- gotoxy(1,w2y2 - w2y1 - 2);
- write(errmsg);
- gotoxy(1,1);
- textcolor(white);
- writeln(' Disk Error ');
- writeln;
- writeln(' DR HD TR SC');
- writeln(' ', drivenumber:2, ' ', headnumber:2, ' ',tracknumber:2, ' ',sectornumber:2);
- writeln;
- writeln;
- writeln(' Any key to ');
- writeln(' continue '); read(kbd,selch);
- end;
- end; {end real record}
-
- Procedure Simulate_Logical;
-
- begin
- clrscr;
- gotoxy(1,1);
- Writeln(' Simulate');
- writeln(' Logical');
- writeln;
- writeln(' Which DOS ');
- writeln(' would you ');
- writeln(' like to ');
- writeln(' simulate ');
- write(' 1 or 2 ?? ');
- read(moden);
- if moden in [1..2] then mode := moden;
- clrscr;
- writeln(' Enter the ');
- writeln(' drive # to');
- writeln(' read.');
- write(' (CR to end): ');
- read(dr);
- if dr in [0..1] then drivenumber := dr;
- disk_reset;
- read_disk_status; {to clear the adapter}
- read_disk_data(drivenumber,0,0,2);
- read_disk_status;
- case diskrecord[0] of
- 255 : t255 := true;
- 254 : t254 := true;
- 253 : t253 := true;
- 252 : t252 := true;
- end;
- clrscr;
- writeln(' Enter the');
- write('logical sector');
- writeln(' # to read: ');
- write(' '); readln(ls);
- {******************************************************************}
- if mode = 1 then begin
- max_sector_count := 8;
- if t255 = true then begin
- tracknumber := trunc(ls / (max_sector_count * 2));
- if odd(trunc(ls / max_sector_count)) then headnumber := 1
- else headnumber := 0;
- end;
- if t254 = true then begin
- tracknumber := trunc(ls / max_sector_count);
- headnumber := 0;
- end;
- sectornumber := (ls mod max_sector_count) + 1;
- end;
- {********************************************************************}
- if mode = 2 then begin
- max_sector_count := 9;
- if ls <= (max_sector_count * 40) - 1 then begin
- tracknumber := trunc(ls / max_sector_count);
- headnumber := 0;
- end;
- if t253 = true then begin
- if ls > (max_sector_count * 40) - 1 then begin
- tracknumber := trunc((ls - ((max_sector_count * 40) - 1)) / max_sector_count);
- headnumber := 1;
- end;
- end;
- sectornumber := (ls mod max_sector_count) + 1;
- end;
- read_disk_data(drivenumber,headnumber,tracknumber,sectornumber);
- read_disk_status;
- if diskstatus = 0 then begin
- for k := 0 to 511 do begin
- altered_byte[k] := false;
- end;
- textcolor(green);
- gotoxy(1,w2y2 - w2y1 - 2);
- write(errmsg);
- textcolor(white);
- showsector(diskrecord);
- clrscr;
- gotoxy(1,1);
- writeln(' Do you wish');
- write(' to alter this');
- writeln(' record (Y/N)');
- read(selch);
- If Upcase(selch)='Y' then begin
- repeat
- clrscr;
- gotoxy(1,1);
- Writeln(' Enter the ');
- writeln(' positon of');
- writeln(' the byte to');
- writeln(' change. ');
- write('( 0-1FF, CR to end): ');
- ReadLn(V);
- C:=Hex2Int4(V,-1);
- If (C >= 0) And (C < 511) Then begin
- clrscr;
- gotoxy(1,1);
- Writeln(' Enter new');
- writeln(' value [',Int2Hex2(diskrecord[C]),']: ');
- ReadLn(V);
- If Length(V) > 1 Then
- If V[1] In ['''','"'] Then diskrecord[C] := Ord(V[2])
- Else diskrecord[C] := Hex2Int4(V,diskrecord[C])
- Else diskrecord[C] := Hex2Int4(V,diskrecord[C]);
- Changed := True;
- if changed = true then altered_byte[c] := true;
- End
- Else C := -1;
- Until C = -1;
- showsector(diskrecord);
- If Changed then begin
- gotoxy(1,1); clrscr;
- Write(' Write changes');
- writeln(' back to real');
- writeln(' sector # ');
- writeln(' DR HD TR SC');
- writeln(' ', drivenumber:2, ' ', headnumber:2, ' ',tracknumber:2, ' ',sectornumber:2);
- writeln;
- write('DR LS# MCT MDE');
- writeln(dr:2, ' ', ls:3, ' ', max_sector_count:2, ' ', mode:1);
- writeln(' (Y/N)? ');
- Read(W);
- If Upcase(W)='Y' then begin
- Write_disk_data(drivenumber,headnumber,tracknumber,sectornumber);
- read_disk_status;
- if diskstatus = 0 then textcolor(green)
- else textcolor(20);
- gotoxy(1,w2y2 - w2y1 - 2);
- writeln(errmsg);
- textcolor(white);
- End; {end write back}
- end; {end test for changed}
- end; {end change record (y/n)}
- end; { good complete from read}
- if diskstatus <> 0 then begin
- window(w1x1,w1y1,w1x2,w1y2);
- clrscr;
- window(w2x1 + 1, w2y1 + 1, w2x2 - 1, w2y2 - 1);
- clrscr;
- textcolor(20);
- gotoxy(1,w2y2 - w2y1 - 2);
- write(errmsg);
- gotoxy(1,1);
- textcolor(white);
- writeln(' Disk Error ');
- writeln;
- writeln(' DR HD TR SC');
- writeln(' ', drivenumber:2, ' ', headnumber:2, ' ',tracknumber:2, ' ',sectornumber:2);
- writeln;
- write('DR LS# MCT MDE');
- writeln(dr:2, ' ', ls:3, ' ', max_sector_count:2, ' ', mode:1);
- writeln;
- writeln(' Any key to ');
- writeln(' continue '); read(kbd,selch);
- end;
- end; {end sim.log record}
-
-
- Procedure Logical_Read;
- begin
- clrscr;
- writeln(' Logical Read');
- writeln;
- writeln(' Drive Sector');
- writeln(' ', dr:2, ' ', ls:4);
- writeln;
- writeln(' Enter the ');
- writeln(' drive # to');
- writeln(' read.');
- writeln(' (CR to end): ');
- readln(DR);
- If DR In [0..25] then begin
- clrscr;
- writeln(' Enter the');
- write('logical sector');
- writeln(' # to read: ');
- readln(ls);
- Result:=ReadSectors(diskrecord,DR,1,LS);
- if result = 0 then begin
- for k := 0 to 511 do begin
- altered_byte[k] := false;
- end;
- textcolor(green);
- gotoxy(1,w2y2 - w2y1 - 2);
- WriteLn(' Result = ',Result);
- Changed := False;
- textcolor(white);
- ShowSector(diskrecord);
- clrscr;
- gotoxy(1,1);
- writeln(' Do you wish');
- write(' to alter this');
- writeln(' record (Y/N)');
- read(selch);
- If Upcase(selch) = 'Y' then begin
- repeat
- clrscr;
- gotoxy(1,1);
- Writeln(' Enter the ');
- writeln(' positon of');
- writeln(' the byte to');
- writeln(' change. ');
- write('( 0-1FF, CR to end): ');
- ReadLn(V);
- C:=Hex2Int4(V,-1);
- If (C >= 0) And (C < 511) then begin
- clrscr;
- gotoxy(1,1);
- Writeln(' Enter new');
- writeln(' value [',Int2Hex2(diskrecord[C]),']: ');
- ReadLn(V);
- If Length(V) > 1 Then
- If V[1] In ['''','"'] then diskrecord[C] := Ord(V[2])
- Else diskrecord[C] := Hex2Int4(V,diskrecord[C])
- Else diskrecord[C] := Hex2Int4(V,diskrecord[C]);
- Changed := True;
- if changed = true then altered_byte[c] := true;
- End
- Else C := -1;
- Until C = -1;
- showsector(diskrecord);
- If Changed then begin
- clrscr;
- gotoxy(1,1);
- Write(' Write changes');
- writeln(' back to');
- writeln(' drive', DR:2);
- writeln(' sector ',LS:4);
- writeln(' (Y/N)? ');
- Read(W);
- If Upcase(W) = 'Y' then begin
- Result := WriteSectors(diskrecord,DR,1,LS);
- gotoxy(1,w2y2 - w2y1 - 2);
- WriteLn('Result = ',Result);
- end; {end write of new data}
- end; {end sample for changed data}
- end; {test for really want to change}
- end; { good read }
- if result <> 0 then begin
- window(w1x1,w1y1,w1x2,w1y2);
- clrscr;
- window(w2x1 + 1, w2y1 + 1, w2x2 - 1, w2y2 - 1);
- clrscr;
- textcolor(20);
- gotoxy(1,w2y2 - w2y1 - 2);
- writeLn('Result = ',Result);
- gotoxy(1,1);
- textcolor(white);
- writeln(' Disk Error ');
- writeln;
- writeln(' drive', DR:2);
- writeln(' sector ',LS:4);
- writeln;
- writeln;
- writeln(' Any key to ');
- writeln(' continue '); read(kbd,selch);
- end;
- end; {end dr valid}
- end; {logical read}
-
-
- begin
- drivenumber := 0;
- headnumber := 0;
- tracknumber := 0;
- sectornumber := 1;
- dr := 0;
- ls := 0;
- mode := 2;
- selch := ' ';
- textcolor(white);
- window(1,1,80,25); {define the screen}
- textcolor(yellow);
- gotoxy(w2x1,w2y1); write(chr(201));
- for x := w2x1 + 1 to w2x2 - 1 do write(chr(205));
- write(chr(187));
- for y := w2y1 + 1 to w2y2 - 1 do
- begin
- gotoxy(w2x1,y);
- write(chr(186), ' ':w2x2 - w2x1 - 1, chr(186))
- end;
- gotoxy(w2x1,w2y2); write(chr(200));
- for x := w2x1 + 1 to w2x2 - 1 do write(chr(205));
- write(chr(188));
- repeat
- FillChar(diskrecord,SizeOf(diskrecord),'z');
- for k := 0 to 511 do begin
- altered_byte[k] := false;
- end;
- disktype := ' ';
- t255 := false;
- t254 := false;
- t253 := false;
- t252 := false;
- window(w1x1,w1y1,w1x2,w1y2);
- clrscr;
- window(w2x1 + 1, w2y1 + 1, w2x2 - 1, w2y2 - 1);
- clrscr;
- gotoxy(1,1);
- textcolor(white);
- writeln(' DISK READ '); writeln;
- writeln(' Enter Mode'); writeln;
- writeln(' (r)eal');
- writeln(' (l)ogical');
- write(' (s)im.logical');
- writeln(' e(x)it');
- read(kbd,selch);
- if upcase(selch) = 'R' then real_read;
- if upcase(selch) = 'L' then logical_read;
- if upcase(selch) = 'S' then simulate_logical;
- until selch = 'x';
- window(1,1,80,25);
- clrscr;
- End.