home *** CD-ROM | disk | FTP | other *** search
- program TRAnsfer_Msdos_Disk_Files ;
- {*
- * TRAnsfer_Msdos_Disk_Files, TraMDF
- * --------------------------------
- *
- * Transfer files between a MS-DOS disk and CP/M disks on a CP/M host,
- * using a SWEEP-like user interface. This program supports in principle
- * all the disk formats which are supported by the hardware and the BIOS
- * of the CP/M host, thus it supports 5,25" drives (160 KByte, 180 KByte,
- * 320 KByte and 360 KByte) as well as 3,5" drives (720 KByte) if your
- * host permits.
- *
- * This program is a rewrite of the program TRANSFER of David Koski. It
- * is written specifically for the Aster CT-80, using the extensions of
- * its BIOS. The system dependent parts are concentrated in a few
- * procedures to ease migration to other CP/M hosts.
- *
- * Written by W.J.M. Nelis (NELIS@NLR.NL).
- * Version 1.0 199110 Initial release
- *}
-
- {$A+} { Generate NON-recursive code }
- {$C+} { Do check for ^C and ^S during console output }
- {$R-} { Do NOT check all subrange variables to be within range }
- {$U-} { Do NOT check for ^C continuously }
- {$V+} { Check length of string parameters }
- {$W2} { Allow up to 2 simultanous active WITH statements }
-
- {* ----- P R O G R A M M I N G N O T E S -----
- *
- * o A CP/M sector of 128 bytes is consistently called a 'record', while an
- * MS-DOS sector is called a 'sector'.
- * o Each time a BIOS driveselect is performed for some operation, the BDOS
- * 'current' drive must be reselected upon completion of the operation: the
- * BDOS and BIOS 'current' drive MUST be the same whenever CP/M disk I/O is
- * performed.
- *}
-
- {$ICONSOLE.UNT} { Console routines }
- {$IEXTFN.UNT} { Extended CP/M file names }
- (* {$IWINDOW.UNT} { Simple windowing mechanism } *)
-
- {$ITRAMDF.IF0} { Constants/Types/Global variables & Error handling }
- {$ITRAMDF.IF1} { Elementary MS-DOS disk I/O routines }
- {$ITRAMDF.IF2} { Filelist manipulations }
- {$ITRAMDF.IF3} { MS-DOS file system }
- {$IMENU.UNT} { Menu primitives }
- {$ITRAMDF.IF4} { CP/M file manager functions }
- {$ITRAMDF.IF5} { MS-DOS file manager functions }
- {$ITRAMDF.IF6} { Second level menu's }
-
- procedure ExecutePrologue ;
- {*
- * Preset the global variables of this program.
- *}
-
- procedure DetermineDriveAttributes ;
- {*
- * Determine the set of configured drives, the set of floppy disk drives
- * and the attributes of each of the configured drives. This procedure
- * depends very much on the BIOS implementation: it has to be adapted to
- * your particular CP/M host.
- *
- * The following variables are set by this procedure:
- * ConfiguredDrives ( The set of drives eligible as CP/M drive ),
- * FloppyDrives ( The set of drives eligible as MS-DOS drive ) and
- * DriveAttribute ( The attributes of each of the drives ).
- *
- * The attributes to be saved for each of the drives in ConfiguredDrives are:
- * DpbAddress : A pointer to the DPB needed to modify the DPB for MS-DOS
- * disk I/O. In case the DPB is extended with physical disk information,
- * the pointer can be used to retrieve drive attributes.
- * DevAddress : The physical address of the floppy drive. A non-floppy drive
- * is assigned 'physical' address 255. The MS-DOS drive is assigned
- * address 254 whenever it is not assigned to any physical (floppy) drive.
- * The physical addresses of the selected CP/M drive and the MS-DOS drive
- * are never the same. This will inhibit one to assign both the CP/M and
- * the MS-DOS drive to the same physical drive.
- * Cylinders : The number of cylinders of the floppy drive, which is either
- * 40 or 80.
- * Heads : The number of heads of the floppy drive, which is either 1
- * or 2.
- *
- *}
- var
- PtrDPH : Integer ; { Address of DPH }
- PtrDpb : ^DPBs ; { Address of DPB (of XLT in fact) }
- DriveName: Char ; { Loop control variable }
- Drive : Integer ; { Ordinal of drive DriveName }
-
- function ContentsOf( Location: Integer ) : Integer ;
- {*
- * Fetch the 16-bit value at the specified location.
- *}
- begin
- ContentsOf:= Mem[Location] + (Mem[Succ(Location)] shl 8) ;
- end ; { of ContentsOf }
-
- begin
- ConfiguredDrives:= [] ; { Clear the set of configured drives }
- FloppyDrives := [] ; { Clear the set of floppy disk drives }
-
- for DriveName:= 'A' to 'P' do
- with DriveAttribute[DriveName] do
- begin
- Drive := Ord(DriveName) - Ord('A') ;
- PtrDPH:= BiosHL( SelectDrive, Drive ) ;
- if PtrDPH=0 then
- {*
- * There is no drive configured with name DriveName. Preset all
- * fields to zero and keep this drive out of the two sets.
- *}
- begin
- DpbAddress:= Nil ;
- DevAddress:= 0 ;
- Cylinders := 0 ;
- Heads := 0 ;
- end
- else
- {*
- * There is a drive configured with name DriveName. Enter it in the set
- * of configured drives and preset the fields as if it is NOT a floppy
- * disk drive.
- *}
- begin
- ConfiguredDrives:= ConfiguredDrives + [DriveName] ;
- PtrDpb:= Ptr( ContentsOf(PtrDPH+10) - 26 ) ; { SizeOf(XLT) = 26 }
-
- DpbAddress:= PtrDpb ; { Address of DPB }
- DevAddress:= 255 ; { Indicate a non-floppy drive }
- Cylinders := 0 ; { Cylinder count is irrelevant }
- Heads := 2 ; { All my drives have at least two heads }
- if (PtrDpb^.FNO and $C0) = $00 then
- {*
- * The drive is a floppy disk drive. Enter it also in the set of floppy disk
- * drives and determine the number of cylinders for this drive. Note that it
- * is assumed that there are only two possibilities for this number, either
- * 40 or 80 cylinders.
- *}
- begin
- FloppyDrives:= FloppyDrives + [DriveName] ;
- DevAddress := PtrDpb^.PDA ; { Fetch physical drive address }
- if ( PtrDpb^.PCD > 45) or { 80 cylinder drive }
- ((PtrDpb^.FNO and $10) <> $00) then { double step is selected }
- Cylinders:= 80
- else
- Cylinders:= 40 ;
- end ; { of if }
- end ; { of else }
- end ; { of with/for }
-
- Bios( SelectDrive, CpmCurrentDrive ) ; { Restore current drive in BIOS }
- end ; { of DetermineDriveAttributes }
-
- begin
- {*
- * Set ALL the global variables to zero: this will minimise the amount of
- * code needed to preset them all seperately! Only those variables with an
- * initial non-zero value need to be preset explicitly.
- *}
- FillChar( FirstGlobalVariable, { Preset ALL global variables to zero }
- Addr(LastGlobalVariable)-Addr(FirstGlobalVariable), 0 ) ;
- {*
- * Preset those global variables, which do not have a initial value of zero
- * under all circumstances.
- *}
- CpmCurrentDrive:= Bdos( GetCurrentDrive ) ;
- DetermineDriveAttributes ;
- SplitFileName( CpmDriveName, ':.' ) ; { Set default to current }
- CpmDrive := Ord(ExtractDisk(CpmDriveName)) - Ord('A') ;
- CpmDriveAddress:= DriveAttribute[ExtractDisk(CpmDriveName)].DevAddress ;
-
- MsdosDrive := -1 ; { Illegal drive ordinal }
- MsdosDriveName := '?' ; { Drive is unknown }
- MsdosDriveAddress := 254 ; { Unassigned physical drive }
- MsdosDpb := Nil ; { Address of DPB is unknown }
- MsdosPath[0] := '\' ; { Name of root directory }
-
- HeadFileList:= Nil ; { Minimum initialisation of file list }
- PresetFileList ; { Allocate sentinel }
-
- DestinationOs := Cpm ; { Setup initial destination and }
- SourceOs := Msdos ; { source drive indication }
- FileClass := TextFile ; { Default file type }
- { CpmBinFillChar := $00 ; { Default CP/M padding character }
- CpmTxtFillChar := $1A ; { Default CP/M padding character }
- { MsdosFillChar := $00 ; { Default MS-DOS padding character }
- CopyCpmFileAttr := True ; { Copy file attributes from CP/M to MS-DOS }
- CopyMsdosFileAttr:= True ; { Copy file attributes from MS-DOS to CP/M }
- ErrorDetected := False ; { No outstanding errors }
-
- SetTodaysDate( DefaultDate ) ;
- end ; { of ExecutePrologue }
-
- procedure ExecuteEpilogue ;
- {*
- * Set the program exit status back to the entry status.
- *}
- begin
- UninstallMsdosDrive ; { Restore BIOS internal tables }
- Bios( SelectDrive, CpmCurrentDrive ) ; { Just to be sure }
- end ; { of ExecuteEpilogue }
-
- procedure HandleRuntimeError( ErrorNo, ErrorAdr: Integer ) ;
- {*
- * Clean up the things meshed-up outside the TPA (the BIOS tables and
- * the BDOS entry point address) before the default error exit is taken.
- * The latter error handler will display the error message and it will
- * terminate program execution.
- *}
- begin
- ExecuteEpilogue ; { Clean up the BIOS tables }
- UnInitFileNameUnit ; { Restore BDOS entry point address }
- end ; { of HandleRuntimeError }
-
-
- {* -------------------------------------------------------------------------
- * M A I N P R O G R A M
- * ------------------------------------------------------------------------- *}
- begin
- {*
- * Initialise the units, the global variables and define the error handler.
- *}
- InitConsoleUnit ;
- InitFileNameUnit ;
- (* InitWindowUnit ; *)
- InitMenuUnit( 'TRAnsfer_Msdos_Disk_Files v ' + Version ) ;
- ExecutePrologue ;
- ErrorPtr:= Addr( HandleRuntimeError ) ; { Set up own error handling }
- {*
- * Enter a mixed menu and command driven system. The MS-DOS drive MUST be
- * specified, before the file manager can do its job.
- *}
- SetDefaults ; { MS-DOS drive MUST be specified }
- EnterFileManager ; { Enter SWEEP like utility }
- {*
- * Undo the modifications in variables outside the TPA.
- *}
- ExecuteEpilogue ; { Restore BIOS tables }
- UnInitFileNameUnit ; { Remove BDOS shell }
- end.