SN-FDD-UTILS/LD-ISDOS.PAS

355 lines
9.4 KiB
Plaintext

uses
dos, crt,
helpers,
fdc;
const
SEP = '--------------------------------------------------------------------------';
var
tmp: TFDCBbuffer;
drive: byte;
i: integer;
startTrack, maxTrack: byte;
ff: file;
tries, track, head, sector, sc: byte;
out_file_name, d: string;
fdcIOErrorBackup: byte;
maxTries: byte;
testMode, motorOffMethod, showDump: boolean;
c: char;
showDumpSector: byte;
{----------------------------------------------------------------------------}
function fdcGetSpeed(drv: byte): byte;
var
speed_id: byte;
begin
fdcGetSpeed:= 255; { speed unknown }
for speed_id:= 0 to FDC_SPEED_COUNT do
begin
port[FDC_REG_DIR]:= speed_id;
fdcReadSector(drv,0,0,1,FDC_SECTOR_1024,9); { ISDOS specific }
if fdcIOError = FDC_OK then
begin
fdcGetSpeed:= speed_id;
exit;
end;
end;
fdcIOError:= FDC_ERR_SECTOR_NOT_FOUND;
end;
{----------------------------------------------------------------------------}
function GetMaxTrack(param: string): byte;
begin
GetMaxTrack:= 79;
if param[3] = '1' then GetMaxTrack:= 80;
if param[3] = '2' then GetMaxTrack:= 81;
if param[3] = '3' then GetMaxTrack:= 82;
if param[3] = '4' then GetMaxTrack:= 83;
if param[3] = '5' then GetMaxTrack:= 84;
if length(param) = 2 then GetMaxTrack:= 82;
end;
{----------------------------------------------------------------------------}
function GetMaxTries(param: string): byte;
begin
GetMaxTries:= 3;
if param[3] = '4' then GetMaxTries:= 4;
if param[3] = '5' then GetMaxTries:= 5;
if param[3] = '6' then GetMaxTries:= 6;
if param[3] = '7' then GetMaxTries:= 7;
if param[3] = '8' then GetMaxTries:= 8;
if param[3] = '9' then GetMaxTries:= 9;
end;
{----------------------------------------------------------------------------}
begin
ClrScr;
drive:= 0;
startTrack:= 0;
maxTrack:= 79;
out_file_name:= '_isdos.isd';
maxTries:= 5;
testMode:= false;
motorOffMethod:= false;
showDump:= false;
showDumpSector:= 1;
{----------------------------------------------------------------------------}
if ParamCount = 1 then
begin
d:= strlo(ParamStr(1));
{ drive }
if d = 'a:' then drive:= 0;
if d = 'b:' then drive:= 1;
end;
if ParamCount > 1 then
begin
d:= strlo(ParamStr(1));
{ drive }
if d = 'a:' then drive:= 0;
if d = 'b:' then drive:= 1;
d:= strlo(ParamStr(2));
{ out file name}
if d[1] <> '/' then out_file_name:= d;
end;
for i:= 1 to ParamCount do
begin
d:= strlo(ParamStr(i));
if copy(d,1,2) = '/t' then
begin
testMode:= true;
startTrack:= 80;
maxTrack:= GetMaxTrack(d);
continue;
end;
if copy(d,1,2) = '/m' then
begin
maxTrack:= GetMaxTrack(d);
continue;
end;
if copy(d,1,2) = '/r' then
begin
maxTries:= GetMaxTries(d);
continue;
end;
if copy(d,1,2) = '/o' then
begin
motorOffMethod:= true;
continue;
end;
if copy(d,1,2) = '/d' then
begin
showDump:= true;
if (length(d) = 3) and (d[3] = '1') then showDumpSector:= 1;
if (length(d) = 3) and (d[3] = '2') then showDumpSector:= 2;
if (length(d) = 3) and (d[3] = '3') then showDumpSector:= 3;
if (length(d) = 3) and (d[3] = '4') then showDumpSector:= 4;
if (length(d) = 3) and (d[3] = '5') then showDumpSector:= 5;
if (length(d) = 3) and (d[3] = '6') then showDumpSector:= 6;
if (length(d) = 3) and (d[3] = '7') then showDumpSector:= 7;
if (length(d) = 3) and (d[3] = '8') then showDumpSector:= 8;
if (length(d) = 3) and (d[3] = '9') then showDumpSector:= 9;
continue;
end;
end;
{----------------------------------------------------------------------------}
writeln('ZX Spectrum Navigator v1.15 Reading iS-DOS floppy disk');
writeln('https://zxsn.ru, RomanRom2@gmail.com');
writeln('Copyright (c) 1996-2026 RomanRom2');
writeln(SEP);
if strlo(ParamStr(1)) = '/h' then
begin
writeln('LD-ISDOS.EXE drive|key <file> <keys>');
writeln(' - key /dN try to show dump of track 0 head 0 sector N');
writeln(' by default N=1, means /d is the same /d1');
writeln(' - key /o enable MotorOff method each 4,6,8 tries');
writeln(' - key /rN set max tries to read bad sector');
writeln(' by default N=5');
writeln(' - key /mN enable 8N tracks, N = 1..5 means 81-85 tracks');
writeln(' /m is the same /m3 for 83');
writeln('by default drive [A:], file name gets from disk name');
writeln(SEP);
writeln('Examples:');
writeln('LD-ISDOS.EXE /m5 - dump disk A: names as DiskName with max tracks');
writeln('LD-ISDOS.EXE b: - dump disk B: names as DiskName');
writeln('LD-ISDOS.EXE a: MYDSK - dump disk A: names as MYDSK');
writeln('LD-ISDOS.EXE a: MYDSK /m2 - dump disk A: names as MYDSK with 82 tracks');
writeln('LD-ISDOS.EXE a: /d9 - dump disk A: names as DiskName with dump sector 9');
writeln('LD-ISDOS.EXE /d /r2 - dump disk A: names as DiskName with dump sector 1');
writeln(' and 2 retries to read bad sectors');
end
else
begin
writeln('LD-ISDOS.EXE /h - for help');
end;
writeln(SEP);
writeln;
if strlo(ParamStr(1)) = '/h' then exit;
{----------------------------------------------------------------------------}
writeln('Drive ',chr(drive+65),': is initializing...');
fdcInit(drive, FDC_SECTOR_1024);
if fdcIOError <> FDC_OK then
begin
writeln('FDC init error ['+fdcErrorStr(fdcIOError)+']');
fdcRecalibrate(drive);
fdcMotorOff;
exit;
end;
writeln(fdcErrorStr(fdcIOError),', ',fdcSpeedStr(fdcGetSpeed(drive)));{}
{ do not show it in test mode }
if not testMode then
begin
{ check 1st sector for disk name }
fdcReadSector(drive,0,0,1,FDC_SECTOR_1024,9);
if fdcIOError <> FDC_OK then
begin
writeln('1st sector read error ['+fdcErrorStr(fdcIOError)+']');
fdcRecalibrate(drive);
fdcMotorOff;
exit;
end;
{ get disk name }
d:=''; for i:=1 to 8 do if fdcBuf[i+2]<>32 then d:=d+chr(fdcBuf[i+2]);
if out_file_name = '_isdos.isd' then out_file_name:= hob2pc(d)+'.isd';;
write('Disk name: [',d,']');
out_file_name:= CheckEx(out_file_name);
writeln(' (',out_file_name,')');
if motorOffMethod then writeln('MotorOff method each 4,6,8 tries is enabled');
if showDump then
begin
{ dump 1st sector }
fdcReadSector(drive,0,0,showDumpSector,FDC_SECTOR_1024,9);
writeln(SEP);
for i:= 0 to 15 do
begin
for track:= 0 to 15 do
begin
gotoxy((track+1)*3,wherey); write(dec2hex(strr(fdcBuf[1+i*16+track])));
gotoxy(51+(track+1),wherey);
if fdcBuf[1+i*16+track]>31 then write(chr(fdcBuf[1+i*16+track])) else write('.');
end;
writeln;
end;
writeln(SEP);
writeln('ESC - cancel, any key - continue');
c:= readkey;
if c = #27 then
begin
writeln;
writeln('Canceled.');
fdcRecalibrate(drive);
fdcMotorOff;
exit;
end;
end;
writeln;
writeln('Dumping ',maxTrack+1,' tracks...');
end
else
begin
writeln;
writeln('TEST [',startTrack,'..',maxTrack+1,'] TRACKS MODE');
end;
{----------------------------------------------------------------------------}
if not testMode then
begin
{ do not dump in test mode }
assign(ff, out_file_name);
rewrite(ff, 1);
end;
for track:= startTrack to maxTrack do
begin
fdcSeek(drive, track);
for head:= 0 to 1 do
Begin
for i:=1 to 5*1024 do tmp[i]:= 0; { empty buffer by zero }
for sector:= 1 to 5 do
begin
if keypressed then break;
sc:= sector;
if sector = 5 then sc:= 9;
write('Track:',track:2,' Head:',head:1,' Sector:',sc,' ');
{ mark sector as a bad sector }
for i:=1 to 1024 do tmp[(sector-1)*1024+i]:= ord('B');
for tries:= 1 to maxTries do
begin
if keypressed then break;
fdcReadSector(drive+(head shl 2),track,head,sc,FDC_SECTOR_1024,9);
fdcIOErrorBackup:= fdcIOError;
if fdcIOErrorBackup = FDC_OK then break;
write('.');
if motorOffMethod then
begin
if tries in [4,6,8] then
begin
fdcMotorOff;
delay(100);
fdcMotorOn(drive);
continue;
end;
end;
if track > 4 then fdcSeek(drive, track-4) else fdcSeek(drive, 0);
fdcSeek(drive,track);
end;
if fdcIOErrorBackup = FDC_ERR_BAD_SECTOR then
write(fdcErrorStr(fdcIOErrorBackup)+' (saved) '+#13)
else
write(fdcErrorStr(fdcIOErrorBackup)+' '+#13);
if fdcIOErrorBackup <> FDC_OK then writeln;
{ save buffer only if [OK] or [BAD_SECTOR] }
if fdcIOErrorBackup in [FDC_OK, FDC_ERR_BAD_SECTOR] then
for i:=1 to 1024 do tmp[(sector-1)*1024+i]:= fdcBuf[i];
end;
{ do not dump in test mode }
if not testMode then
BlockWrite(ff, tmp, 5*1024); { dump full track }
End;
if KeyPressed then
if ReadKey = #27 then
begin
writeln(#13#10'... break pressed');
break;
end;
end;
{ do not dump in test mode }
if not testMode then
close(ff);
fdcRecalibrate(drive);
fdcMotorOff;
write(#13' ');
writeln(#13#10'Done.'#13#10);
end.