(*********************************************************) (* *) (* a program to transfer files between cp/m and ms-dos *) (* with a cp/m host system *) (* *) (* Written by David Koski 1985 *) (* P.O. Box 1078 *) (* Fort Bragg, CA 95437-1078 *) (* 707/964-0806 *) (* *) (* This program is intended for private non-commertial *) (* use and is considered to be public domain material *) (* *) (*********************************************************) { enhanced versions 1987-1991 by Guenter Radestock } { (eMail: radest@ira.uka.de, Snail: Guenter Radestock, } { irc: gr Lorscherstr. 37 } { D-W-6700 Ludwigshafen 29 } { (FRG) ) } { } { Changes from David Koskis original Version 1.1 (or was it 1.2?) } { o TRANSFER will use the information in the Boot-Sector of } { a DOS-Disk thus allowing to read more disk formats including } { ATARI ST TOS disks (rewrite of identify_msdos) } { o removed double-stepping code } { o do directory writes when writing physically to the DOS-Disk } { o now asks before removing all files on empty input } { o removed lots of other bugs } { o added path command and read from subdirectory } { Changes since Version 1.5 } { o Directory writes are performed only at the end of each } { physical Sector under CP/M 2.2 } { o A Disk Reset is done before each menu-selected write, } { allowing the user to change disks } { o sets the timestamp on DOS Files to the creation date of TRANSFER } { Changes for Version 1.8 } { o Added support for CP/M3. should still work under 2.2 } { though I didn't test it yet } { o MSDOS Directory will now output the amount of free space } { on the DOS-Disk } { removed old bug which caused TRANSFER to crash when attempting } { to copy zero-byte files from DOS } { o SecTrans support may not work anymore now. can't believe it ever } { did anyway. } { o can now be interrupted at startup } { o added paging to directory and map commands } program Transfer; const SecTrans = false; { sector translation for bios read/write } SO = 0; { offset added to sector number } MinSector = 0; MaxFATSize = 5632; Vers = '1.8'; { Version Number } cdyear = 1991; { Creation Date } cdmonth = 9; cdday = 14; SectorSizeMax = 1024; BufferSize = SectorSizeMax; MenuMargin = 18; ClusterSizeMax = 2048; NameSize = 8; TypeSize = 3; First = true; Next = false; EODirectory = $FF; MTDirectory = 1; FoundDir = 0; SectorSize:integer = 512; type SizeArray= Array[1..4] of Byte; Str20 = string[20]; Bufr = array[1..BufferSize] of char; CBufr = array[1..ClusterSizeMax] of char; FATarray = array[1..MaxFATSize] of byte; FAT_ID = (Unidentified,ss8spt,ds8spt,ss9spt,ds9spt,B_20); NameAry = array[1..NameSize] of char; TypeAry = array[1..TypeSize] of char; NameStr = string[20]; PC_FCB = record Name: NameAry; Extention: TypeAry; Attribute: byte; Rsrvd: array[12..21] of byte; Time: integer; Date: integer; ClusterNo: integer; FileSize: SizeArray; end; CpmFCB = record DriveCode: byte; Name: NameAry; Extention: TypeAry; Extent: byte; S1,S2: byte; RC: byte; Rsrvd: array[16..31] of byte; CR: byte; R0,R1,R2: byte; end; var CPM_Buf: array[1..128] of char; Done: boolean; Selection: char; I: integer; cpmnew,dosnew: boolean; MS_DOS_Drive: integer; CPM_Drive: integer; CPM_DriveCh: char; Track: integer; Sector: integer; SecsPerCluster: integer; FAT: FATarray; FATSize: integer; fatnum: integer; RecordsPerSector: integer; DirSecs: integer; NTracks: integer; NSectors: integer; NClusters: integer; Identity: FAT_ID; FirstFATSector: integer; FirstDirSector: integer; {erster Sektor im Directory} FirstDataSector: integer; FirstDataTrack: integer; DirSector: integer; DirTrack: integer; DirSectorCount: integer; DoubleSided: boolean; SingleSided: boolean; DOS_FCB: ^PC_FCB; CPM_FCB: CpmFCB; Buffer: Bufr; DirBuffer: Bufr; DirOffset: integer; DirName: NameStr; ClusterBuffer: CBufr; MaxSector: integer; OutFile: File; BiosError: boolean; VolumeName: boolean; SubDirName: boolean; pathStr: string [31]; {Pfadname} rootSearch: boolean; {Flag, ob im RootDir gesucht wird} dirCluster: integer; {erster DirectoryCluster falls rootSearch=FALSE} cpm3: Boolean; {$I TRANS-00.INC} { bios call function for cpm2.2 and 3.1 } {$I TRANS-01.INC} { main menu, read-write for (dos-)sectors and clusters } {$I TRANS-02.INC} { identify_msdos, dos- search_first and search_next } {$I TRANS-03.INC} { dir_cpm, set msdos path } {$I TRANS-04.INC} { write msdos } {$I TRANS-05.INC} { read msdos, dir msdos, map msdos } procedure EraseMS_DOS; var FileName: Str20; Next,I,Err: integer; CPMFile: File; Cl: integer; Stop: boolean; c: CHAR; begin IdentifyMS_DOS; if not (Identity = Unidentified) then begin ClrScr; writeln; write('File Name to Erase From MS-DOS: '); readln(FileName); IF filename = '' THEN BEGIN write ('Erase all Files (y/n) ?'); REPEAT read (kbd, c); c := upcase (c) UNTIL (c = 'Y') OR (c = 'N'); writeln (c); Stop := (c = 'N') END ELSE Stop := FALSE; writeln; SearchFirst(FileName,Err); while volumeName or subDirName do {Subdir oder VolumeName nicht loeschen} searchNext (fileName, err); if (Err = EODirectory) then write('File Not Found, ') else begin write('Erasing -'); IF NOT stop THEN repeat writeln; for I:= 1 to NameSize do if not (DOS_FCB^.Name[I] = ' ') then write(DOS_FCB^.Name[I]); write('.'); for I:= 1 to TypeSize do write(DOS_FCB^.Extention[I]); Cl:= DOS_FCB^.ClusterNo; if (Cl <= NClusters) then begin Next:= Cl; repeat Cl:= Next; Next:= FATPointer(Cl); SetFATPointer(Cl,0); until ((Next > NClusters) or (Next = 0)); end; DOS_FCB^.Name[1]:= #$E5; WriteSector(DirSector,DirTrack,addr(DirBuffer)); SearchNext(FileName,Err); while volumeName or subDirName do {Subdir oder VolumeName nicht loeschen} searchNext (fileName, err); Stop:= Break; until (Err = EODirectory) or Stop; writeln; writeln; end; if Stop then write('Aborted, '); PutFAT; Continue; end; end; procedure resetPath; { Den Pfad vor Schreiboperationen auf die MSDOS} { Diskette zuruecksetzen} begin if pathStr <> '\' then begin pathStr := '\'; clrscr; gotoxy (12,12); writeln ('The MS-DOS Directory Path was reset to "\".'); gotoxy (12,14); continue end end; (********************) (* *) (* main program *) (* *) (********************) begin cpm3 := (bdos(12) >= $30); ClrScr; writeln('TRANSFER - CP/M <--> MSDOS File Conversion Utility'); writeln('----------------------------------------------------'); repeat biosError := false; cpmnew:=true;dosnew:=true; gotoxy(1,5); write('Which Drive is the MS-DOS Disk in? '); read(KBD,Selection); if Selection = chr(3) then begin write('^C'); halt; end; write(upcase(Selection),':'); MS_DOS_Drive:= ord(upcase(Selection)) - ord('A'); writeln; write('Which drive is the CP/M Disk in? '); read(KBD,CPM_DriveCh); if CPM_DriveCH = chr(3) then begin write('^C'); halt; end; CPM_DriveCh:= upcase(CPM_DriveCh); Write(CPM_DriveCh,':'); CPM_Drive:= ord(upcase(CPM_DriveCh)) - ord('A'); BiosSelect(CPM_Drive); until not BiosError; pathStr := '\'; writeln; {Delay(500);} done:= false; repeat Selection:= MainSelection; ClrScr; case Selection of '1': begin resetPath; WriteMS_DOS end; '2': ReadMS_DOS; '3': DirMS_DOS; '4': MapMS_DOS; '5': DirCPM; '6': begin resetPath; EraseMS_DOS end; '7': showboot; '8': chDir; '9': Done:= True; end; (* case *) until Done; end.