home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / os / cpm / 950 < prev    next >
Encoding:
Internet Message Format  |  1992-07-23  |  6.8 KB

  1. Path: sparky!uunet!caen!hellgate.utah.edu!cc.usu.edu!ivie
  2. From: ivie@cc.usu.edu (CP/M lives!)
  3. Newsgroups: comp.os.cpm
  4. Subject: PX-8 ROM generator 3/3: PXFS.PAS
  5. Message-ID: <1992Jul23.115908.57468@cc.usu.edu>
  6. Date: 23 Jul 92 11:59:07 MDT
  7. Organization: Utah State University
  8. Lines: 353
  9.  
  10. {****************************************************************************
  11. *
  12. * This file implements just enough of a CP/M compatible file-system to
  13. * create files in a disk image of a ROM. In particular, it supports only
  14. * the following operations:
  15. *
  16. *       - Make File
  17. *       - Write Sequential
  18. *       - Close File
  19. *
  20. * These routines assume that they can call:
  21. *
  22. *       - ReadRom( Block_Number : Integer, Var Buffer );
  23. *       - WriteRom( Block_Number : Integer, Buffer );
  24. *
  25. * They also assume that Buffer_Type is predefined as a buffer that can be
  26. * written.
  27. *
  28. ***************************************************************************}
  29.  
  30. Type
  31.   FCB_Name = Array[ 0..10 ] of Char;      { File name and extension }
  32.   Allocation_Map = Array[ 0..15 ] of Byte;{ Disk allocation map }
  33.   Memory_FCB = Record
  34.     DRV : Byte;             { Drive number; high bit writes a deleted FCB
  35.                               when closed. }
  36.     NAME : FCB_Name;        { File name and extension }
  37.     EX : Byte;              { Extent number }
  38.     FIX : Byte;             { Position of this FCB on disk; first FCB is #0 }
  39.     CR : Byte;              { Current record position; high nybble =
  40.                               index into DM, low nybble = record in that one }
  41.     NR : Byte;              { Number of records owned by this FCB }
  42.     DM : Allocation_Map;    { Disk allocation map }
  43.   End;
  44.  
  45.   Disk_FCB = Record
  46.     ET : Byte;              { Entry type: $E5 = deleted file }
  47.     NAME : FCB_Name;        { File name and extension }
  48.     EX : Byte;              { Extent number }
  49.     Reserved1,
  50.     Reserved2 : Byte;       { Reserved; not used }
  51.     NR : Byte;              { Number of records owned by this FCB }
  52.     DM : Allocation_Map;    { Disk allocation map }
  53.   End;
  54.  
  55. Const
  56.   Vector_Valid : Boolean = False; { If true, Vector contains a valid
  57.                                     representation of the owned clusters on
  58.                                     the disk. }
  59.  
  60. Var
  61.   NumClusters : Byte;       { Number of clusters on the drive. }
  62.   FCBBuffer : Array [ 0..3 ] of Disk_FCB;
  63.   Vector : Array [ 0..127 ] of Boolean; { Bit map for drive. }
  64.  
  65. Procedure Zero_Directory( Blocks, FCBs : Integer );
  66. Label 1, 2, 999;
  67. Var Block : Integer;
  68. Begin
  69.  
  70. 1:
  71.   Vector_Valid := False;
  72.   Block := 0;
  73.   FillChar( FCBBuffer, 128, $E5 );
  74.   FCBBuffer[ 0 ].Name[ 0 ] := Chr( $37 );
  75.   FCBBuffer[ 0 ].Name[ 1 ] := Chr( Blocks shr 3 );
  76.   FCBBuffer[ 0 ].DM[ 6 ] := FCBs;
  77.   Goto 2;
  78.  
  79. 2:
  80.   Write_Rom( Block, FCBBuffer );
  81.   FCBs := FCBs - 4;
  82.   Block := Block + 1;
  83.   If( FCBs > 0 ) Then Goto 2;
  84.   Goto 999;
  85.  
  86. 999:
  87. End;
  88.  
  89. Procedure Get_FCB( Var FCB : Memory_FCB );
  90. Label 1, 2, 3, 4, 999;
  91. Var
  92.   Block : Integer;
  93.   FIX : Byte;
  94. Begin
  95.  
  96. 1:
  97.   Block := FCB.FIX shr 2;
  98.   Read_ROM( Block, FCBBuffer );
  99.   FIX := FCB.FIX and 3;
  100.   If( FCBBuffer[ FIX ].ET = $E5 ) Then Goto 3;
  101.   Goto 2;
  102.  
  103. 2:
  104.   FCB.DRV := FCB.DRV and $7f;
  105.   Goto 4;
  106.  
  107. 3:
  108.   FCB.DRV := FCB.DRV or $80;
  109.   Goto 4;
  110.  
  111. 4:
  112.   FCB.NAME := FCBBuffer[ FIX ].NAME;
  113.   FCB.EX := FCBBuffer[ FIX ].EX;
  114.   FCB.NR := FCBBuffer[ FIX ].NR;
  115.   FCB.DM := FCBBuffer[ FIX ].DM;
  116.   Goto 999;
  117.  
  118. 999:
  119. End;
  120.  
  121. Procedure Close_File( FCB : Memory_FCB );
  122. Label 1, 2, 3, 4, 999;
  123. Var
  124.   Block : Integer;
  125.   FIX : Byte;
  126. Begin
  127.  
  128. 1:
  129.   Block := FCB.FIX shr 2;
  130.   Read_Rom( Block, FCBBuffer );
  131.   FIX := FCB.FIX and 3;
  132.   if( ( FCB.DRV and $80 ) <> 0 ) Then Goto 3;
  133.   Goto 2;
  134.  
  135. 2:
  136.   FCBBuffer[ FIX ].ET := 0;
  137.   Goto 4;
  138.  
  139. 3:
  140.   FCBBuffer[ FIX ].ET := $E5;
  141.   Goto 4;
  142.  
  143. 4:
  144.   FCBBuffer[ FIX ].Reserved1 := 0;
  145.   FCBBuffer[ FIX ].Reserved2 := 0;
  146.   FCBBuffer[ FIX ].NAME := FCB.NAME;
  147.   FCBBuffer[ FIX ].EX := FCB.EX;
  148.   FCBBuffer[ FIX ].NR := FCB.NR;
  149.   FCBBuffer[ FIX ].DM := FCB.DM;
  150.   Write_Rom( Block, FCBBuffer );
  151.   Goto 999;
  152.  
  153. 999:
  154. End;
  155.  
  156. Procedure Init_FCB( Var FCB : Memory_FCB );
  157. Begin
  158.   FCB.DRV := FCB.DRV and $7f;
  159.   FCB.FIX := 0;
  160.   FCB.CR := 0;
  161.   FCB.NR := 0;
  162.   FillChar( FCB.DM, 16, 0 );
  163. End;
  164.  
  165. Function Make_File( Var FCB : Memory_FCB ) : Boolean;
  166. Label 1, 2, 3, 4, 5, 6, 7, 999;
  167. Var
  168.   FIX : Byte;
  169.   Block : Integer;
  170.   FCBs : Integer;
  171. Begin
  172.  
  173. 1:
  174.   Init_FCB( FCB );
  175.   FIX := 1;
  176.   Block := 0;
  177.   Read_Rom( Block, FCBBuffer );
  178.   FCBs := FCBBuffer[ 0 ].DM[ 6 ];
  179.   Goto 2;
  180.  
  181. 2:
  182.   If( ( FIX and 3 ) = 0 ) Then Goto 3;
  183.   Goto 4;
  184.  
  185. 3:
  186.   Block := Block + 1;
  187.   Read_Rom( Block, FCBBuffer );
  188.   Goto 4;
  189.  
  190. 4:
  191.   If( FCBBuffer[ FIX and 3 ].ET = $E5 ) Then Goto 5;
  192.   Goto 6;
  193.  
  194. 5:
  195.   FCB.FIX := FIX;
  196.   Close_File( FCB );
  197.   Make_File := True;
  198.   Goto 999;
  199.  
  200. 6:
  201.   FIX := FIX + 1;
  202.   If( FIX < FCBs ) Then Goto 2;
  203.   Goto 7;
  204.  
  205. 7:
  206.   Make_File := False;
  207.   Goto 999;
  208.  
  209. 999:
  210. End;
  211.  
  212. Procedure Build_Vector;
  213. Label 1, 2, 3, 4, 5, 6, 7, 8, 9, 999;
  214. Var
  215.   FIX : Byte;
  216.   Block : Integer;
  217.   FCBs : Byte;
  218.   I, DMIX : Integer;
  219. Begin
  220.  
  221. 1:
  222.   FIX := 1;
  223.   Block := 0;
  224.   For I := 0 to 127 do
  225.     Vector[ I ] := False;
  226.   Read_Rom( Block, FCBBuffer );
  227.   NumClusters := Ord( FCBBuffer[ 0 ].Name[ 1 ] );
  228.   FCBs := FCBBuffer[ 0 ].DM[ 6 ];
  229.   Goto 2;
  230.  
  231. 2:
  232.   If( ( FIX and 3 ) = 0 ) Then Goto 3;
  233.   Goto 4;
  234.  
  235. 3:
  236.   Block := Block + 1;
  237.   Read_Rom( Block, FCBBuffer );
  238.   Goto 4;
  239.  
  240. 4:
  241.   If( FIX < FCBs ) Then Goto 6;
  242.   Goto 5;
  243.  
  244. 5:
  245.   Vector[ 0 ] := True;
  246.   Vector_Valid := True;
  247.   Goto 999;
  248.  
  249. 6:
  250.   If( FCBBuffer[ FIX and 3 ].ET = $E5 ) Then Goto 9;
  251.   Goto 7;
  252.  
  253. 7:
  254.   DMIX := 0;
  255.   Goto 8;
  256.  
  257. 8:
  258.   Vector[ FCBBuffer[ FIX and 3 ].DM[ DMIX ] ] := True;
  259.   DMIX := DMIX + 1;
  260.   If( DMIX < 16 ) Then Goto 8;
  261.   Goto 9;
  262.  
  263. 9:
  264.   FIX := FIX + 1;
  265.   Goto 2;
  266.  
  267. 999:
  268. End;
  269.  
  270. Function Allocate( Var FCB: Memory_FCB ) : Boolean;
  271.  
  272. Label 1, 2, 3, 4, 5, 6, 7, 999;
  273. Var
  274.   CurCluster : Byte;
  275. Begin
  276.  
  277. 1:
  278.   If( Vector_Valid ) Then Goto 3;
  279.   Goto 2;
  280.  
  281. 2:
  282.   Build_Vector;
  283.   Goto 3;
  284.  
  285. 3:
  286.   CurCluster := 0;
  287.   Goto 4;
  288.  
  289. 4:
  290.   If( Vector[ CurCluster ] ) Then Goto 5;
  291.   Goto 6;
  292.  
  293. 5:
  294.   CurCluster := CurCluster + 1;
  295.   If( CurCluster < NumClusters ) Then Goto 4;
  296.   Goto 7;
  297.  
  298. 6:
  299.   FCB.DM[ FCB.CR shr 4 ] := CurCluster;
  300.   Vector[ CurCluster ] := True;
  301.   Allocate := True;
  302.   Goto 999;
  303.  
  304. 7:
  305.   Allocate := False;
  306.   Goto 999;
  307.  
  308. 999:
  309. End;
  310.  
  311. Function Write_Sequential( Var FCB : Memory_FCB; Var Buffer ) :
  312.   Boolean;
  313.  
  314. Label 1, 2, 3, 4, 5, 6, 7, 8, 999;
  315. Var
  316.   Block : Integer;
  317. Begin
  318.  
  319. 1:
  320.   If( FCB.NR > 127 ) Then Goto 2;
  321.   Goto 3;
  322.  
  323. 2:
  324.   Close_File( FCB );
  325.   FCB.EX := FCB.EX + 1;
  326.   If( Make_File( FCB ) ) Then Goto 3;
  327.   Goto 7;
  328.  
  329. 3:
  330.   Block := FCB.DM[ FCB.CR SHR 4 ] * 8;
  331.   If( Block = 0 ) Then Goto 4;
  332.   Goto 5;
  333.  
  334. 4:
  335.   If( Allocate( FCB ) ) Then Goto 3;
  336.   Goto 8;
  337.  
  338. 5:
  339.   Write_Rom( Block + ( FCB.CR and 7 ), Buffer );
  340.   FCB.NR := FCB.NR + 1;
  341.   FCB.CR := FCB.CR + 1;
  342.   Write_Sequential := True;
  343.   If( ( FCB.CR and 7 ) = 0 ) Then Goto 6;
  344.   Goto 999;
  345.  
  346. 6:
  347.   FCB.CR := ( FCB.CR + $10 ) and $F0;
  348.   Goto 999;
  349.  
  350. 7:
  351.   Writeln( '%Write_Sequential: Directory full.' );
  352.   Write_Sequential := False;
  353.   Goto 999;
  354.  
  355. 8:
  356.   Writeln( '%Write_Sequential: ROM full.' );
  357.   Write_Sequential := False;
  358.   Goto 999;
  359.  
  360. 999:
  361. End;
  362.  
  363.