home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / dskutl / swp-ms10.ark / TRAMDF.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-09-27  |  9.9 KB  |  242 lines

  1. program TRAnsfer_Msdos_Disk_Files ;
  2. {*
  3.  *             TRAnsfer_Msdos_Disk_Files, TraMDF
  4.  *             --------------------------------
  5.  *
  6.  * Transfer files between a MS-DOS disk and CP/M disks on a CP/M host,
  7.  * using a SWEEP-like user interface.  This program supports in principle
  8.  * all the disk formats which are supported by the hardware and the BIOS
  9.  * of the CP/M host, thus it supports 5,25" drives (160 KByte, 180 KByte,
  10.  * 320 KByte and 360 KByte) as well as 3,5" drives (720 KByte) if your
  11.  * host permits.
  12.  *
  13.  * This program is a rewrite of the program TRANSFER of David Koski. It
  14.  * is written specifically for the Aster CT-80, using the extensions of
  15.  * its BIOS.  The system dependent parts are concentrated in a few
  16.  * procedures to ease migration to other CP/M hosts.
  17.  *
  18.  * Written by W.J.M. Nelis (NELIS@NLR.NL).
  19.  *  Version 1.0  199110  Initial release
  20.  *}
  21.  
  22. {$A+}  { Generate NON-recursive code }
  23. {$C+}  { Do check for ^C and ^S during console output }
  24. {$R-}  { Do NOT check all subrange variables to be within range }
  25. {$U-}  { Do NOT check for ^C continuously }
  26. {$V+}  { Check length of string parameters }
  27. {$W2}  { Allow up to 2 simultanous active WITH statements }
  28.  
  29. {* ----- P R O G R A M M I N G   N O T E S -----
  30.  *
  31.  * o A CP/M sector of 128 bytes is consistently called a 'record', while an
  32.  *   MS-DOS sector is called a 'sector'.
  33.  * o Each time a BIOS driveselect is performed for some operation, the BDOS
  34.  *   'current' drive must be reselected upon completion of the operation: the
  35.  *   BDOS and BIOS 'current' drive MUST be the same whenever CP/M disk I/O is
  36.  *   performed.
  37.  *}
  38.  
  39. {$ICONSOLE.UNT} { Console routines }
  40. {$IEXTFN.UNT}   { Extended CP/M file names }
  41. (* {$IWINDOW.UNT}  { Simple windowing mechanism } *)
  42.  
  43. {$ITRAMDF.IF0}  { Constants/Types/Global variables & Error handling }
  44. {$ITRAMDF.IF1}  { Elementary MS-DOS disk I/O routines }
  45. {$ITRAMDF.IF2}  { Filelist manipulations }
  46. {$ITRAMDF.IF3}  { MS-DOS file system }
  47. {$IMENU.UNT}    { Menu primitives }
  48. {$ITRAMDF.IF4}  { CP/M file manager functions }
  49. {$ITRAMDF.IF5}  { MS-DOS file manager functions }
  50. {$ITRAMDF.IF6}  { Second level menu's }
  51.  
  52. procedure ExecutePrologue ;
  53. {*
  54.  * Preset the global variables of this program.
  55.  *}
  56.  
  57.  procedure DetermineDriveAttributes ;
  58.  {*
  59.   * Determine the set of configured drives, the set of floppy disk drives
  60.   * and the attributes of each of the configured drives.  This procedure
  61.   * depends very much on the BIOS implementation: it has to be adapted to
  62.   * your particular CP/M host.
  63.   *
  64.   * The following variables are set by this procedure:
  65.   *  ConfiguredDrives ( The set of drives eligible as CP/M drive ),
  66.   *  FloppyDrives     ( The set of drives eligible as MS-DOS drive ) and
  67.   *  DriveAttribute   ( The attributes of each of the drives ).
  68.   *
  69.   * The attributes to be saved for each of the drives in ConfiguredDrives are:
  70.   *  DpbAddress : A pointer to the DPB needed to modify the DPB for MS-DOS
  71.   *    disk I/O.  In case the DPB is extended with physical disk information,
  72.   *    the pointer can be used to retrieve drive attributes.
  73.   *  DevAddress : The physical address of the floppy drive.  A non-floppy drive
  74.   *    is assigned 'physical' address 255.  The MS-DOS drive is assigned
  75.   *    address 254 whenever it is not assigned to any physical (floppy) drive.
  76.   *    The physical addresses of the selected CP/M drive and the MS-DOS drive
  77.   *    are never the same.  This will inhibit one to assign both the CP/M and
  78.   *    the MS-DOS drive to the same physical drive.
  79.   *  Cylinders  : The number of cylinders of the floppy drive, which is either
  80.   *    40 or 80.
  81.   *  Heads      : The number of heads of the floppy drive, which is either 1
  82.   *    or 2.
  83.   *
  84.   *}
  85.  var
  86.     PtrDPH   : Integer ;  { Address of DPH }
  87.     PtrDpb   :   ^DPBs ;  { Address of DPB (of XLT in fact) }
  88.     DriveName:    Char ;  { Loop control variable }
  89.     Drive    : Integer ;  { Ordinal of drive DriveName }
  90.  
  91.   function ContentsOf( Location: Integer ) : Integer ;
  92.   {*
  93.    * Fetch the 16-bit value at the specified location.
  94.    *}
  95.   begin
  96.      ContentsOf:= Mem[Location] + (Mem[Succ(Location)] shl 8) ;
  97.   end ;  { of ContentsOf }
  98.  
  99.  begin
  100.     ConfiguredDrives:= [] ;  { Clear the set of configured drives }
  101.     FloppyDrives    := [] ;  { Clear the set of floppy disk drives }
  102.  
  103.     for DriveName:= 'A' to 'P' do
  104.       with DriveAttribute[DriveName] do
  105.        begin
  106.         Drive := Ord(DriveName) - Ord('A') ;
  107.         PtrDPH:= BiosHL( SelectDrive, Drive ) ;
  108.         if PtrDPH=0 then
  109.  {*
  110.   * There is no drive configured with name DriveName.  Preset all
  111.   * fields to zero and keep this drive out of the two sets.
  112.   *}
  113.          begin
  114.           DpbAddress:= Nil ;
  115.           DevAddress:=   0 ;
  116.           Cylinders :=   0 ;
  117.           Heads     :=   0 ;
  118.          end
  119.         else
  120.  {*
  121.   * There is a drive configured with name DriveName.  Enter it in the set
  122.   * of configured drives and preset the fields as if it is NOT a floppy
  123.   * disk drive.
  124.   *}
  125.          begin
  126.           ConfiguredDrives:= ConfiguredDrives + [DriveName] ;
  127.           PtrDpb:= Ptr( ContentsOf(PtrDPH+10) - 26 ) ;  { SizeOf(XLT) = 26 }
  128.  
  129.           DpbAddress:= PtrDpb ;  { Address of DPB }
  130.           DevAddress:=    255 ;  { Indicate a non-floppy drive }
  131.           Cylinders :=      0 ;  { Cylinder count is irrelevant }
  132.           Heads     :=      2 ;  { All my drives have at least two heads }
  133.           if (PtrDpb^.FNO and $C0) = $00 then
  134.  {*
  135.   * The drive is a floppy disk drive.  Enter it also in the set of floppy disk
  136.   * drives and determine the number of cylinders for this drive.  Note that it
  137.   * is assumed that there are only two possibilities for this number, either
  138.   * 40 or 80 cylinders.
  139.   *}
  140.            begin
  141.             FloppyDrives:= FloppyDrives + [DriveName] ;
  142.             DevAddress  := PtrDpb^.PDA ;  { Fetch physical drive address }
  143.             if ( PtrDpb^.PCD           >  45) or   { 80 cylinder drive }
  144.                ((PtrDpb^.FNO and $10) <> $00) then { double step is selected }
  145.               Cylinders:= 80
  146.             else
  147.               Cylinders:= 40 ;
  148.            end ;  { of if }
  149.          end ;  { of else }
  150.        end ;  { of with/for }
  151.  
  152.     Bios( SelectDrive, CpmCurrentDrive ) ;  { Restore current drive in BIOS }
  153.  end ;  { of DetermineDriveAttributes }
  154.  
  155. begin
  156. {*
  157.  * Set ALL the global variables to zero: this will minimise the amount of
  158.  * code needed to preset them all seperately!  Only those variables with an
  159.  * initial non-zero value need to be preset explicitly.
  160.  *}
  161.    FillChar( FirstGlobalVariable,       { Preset ALL global variables to zero }
  162.              Addr(LastGlobalVariable)-Addr(FirstGlobalVariable), 0 ) ;
  163. {*
  164.  * Preset those global variables, which do not have a initial value of zero
  165.  * under all circumstances.
  166.  *}
  167.    CpmCurrentDrive:= Bdos( GetCurrentDrive ) ;
  168.    DetermineDriveAttributes ;
  169.    SplitFileName( CpmDriveName, ':.' ) ;  { Set default to current }
  170.    CpmDrive       := Ord(ExtractDisk(CpmDriveName)) - Ord('A') ;
  171.    CpmDriveAddress:= DriveAttribute[ExtractDisk(CpmDriveName)].DevAddress ;
  172.  
  173.    MsdosDrive        :=  -1 ;  { Illegal drive ordinal }
  174.    MsdosDriveName    := '?' ;  { Drive is unknown }
  175.    MsdosDriveAddress := 254 ;  { Unassigned physical drive }
  176.    MsdosDpb          := Nil ;  { Address of DPB is unknown }
  177.    MsdosPath[0]      := '\' ;  { Name of root directory }
  178.  
  179.    HeadFileList:= Nil ;  { Minimum initialisation of file list }
  180.    PresetFileList     ;  { Allocate sentinel }
  181.  
  182.    DestinationOs    :=      Cpm ;  { Setup initial destination and }
  183.    SourceOs         :=    Msdos ;  {  source drive indication }
  184.    FileClass        := TextFile ;  { Default file type }
  185. {  CpmBinFillChar   :=      $00 ;  { Default CP/M padding character }
  186.    CpmTxtFillChar   :=      $1A ;  { Default CP/M padding character }
  187. {  MsdosFillChar    :=      $00 ;  { Default MS-DOS padding character }
  188.    CopyCpmFileAttr  :=     True ;  { Copy file attributes from CP/M to MS-DOS }
  189.    CopyMsdosFileAttr:=     True ;  { Copy file attributes from MS-DOS to CP/M }
  190.    ErrorDetected    :=    False ;  { No outstanding errors }
  191.  
  192.    SetTodaysDate( DefaultDate ) ;
  193. end ;  { of ExecutePrologue }
  194.  
  195. procedure ExecuteEpilogue ;
  196. {*
  197.  * Set the program exit status back to the entry status.
  198.  *}
  199. begin
  200.    UninstallMsdosDrive ;  { Restore BIOS internal tables }
  201.    Bios( SelectDrive, CpmCurrentDrive ) ;  { Just to be sure }
  202. end ;  { of ExecuteEpilogue }
  203.  
  204. procedure HandleRuntimeError( ErrorNo, ErrorAdr: Integer ) ;
  205. {*
  206.  * Clean up the things meshed-up outside the TPA (the BIOS tables and
  207.  * the BDOS entry point address) before the default error exit is taken.
  208.  * The latter error handler will display the error message and it will
  209.  * terminate program execution.
  210.  *}
  211. begin
  212.    ExecuteEpilogue ;     { Clean up the BIOS tables }
  213.    UnInitFileNameUnit ;  { Restore BDOS entry point address }
  214. end ;  { of HandleRuntimeError }
  215.  
  216.  
  217. {* -------------------------------------------------------------------------
  218.  *                          M A I N   P R O G R A M
  219.  * ------------------------------------------------------------------------- *}
  220. begin
  221. {*
  222.  * Initialise the units, the global variables and define the error handler.
  223.  *}
  224.    InitConsoleUnit  ;
  225.    InitFileNameUnit ;
  226. (*   InitWindowUnit   ;  *)
  227.    InitMenuUnit( 'TRAnsfer_Msdos_Disk_Files  v ' + Version ) ;
  228.    ExecutePrologue  ;
  229.    ErrorPtr:= Addr( HandleRuntimeError ) ;  { Set up own error handling }
  230. {*
  231.  * Enter a mixed menu and command driven system.  The MS-DOS drive MUST be
  232.  * specified, before the file manager can do its job.
  233.  *}
  234.    SetDefaults      ;  { MS-DOS drive MUST be specified }
  235.    EnterFileManager ;  { Enter SWEEP like utility }
  236. {*
  237.  * Undo the modifications in variables outside the TPA.
  238.  *}
  239.    ExecuteEpilogue    ;  { Restore BIOS tables }
  240.    UnInitFileNameUnit ;  { Remove BDOS shell }
  241. end.
  242.