home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!caen!hellgate.utah.edu!cc.usu.edu!ivie
- From: ivie@cc.usu.edu (CP/M lives!)
- Newsgroups: comp.os.cpm
- Subject: PX-8 ROM generator 3/3: PXFS.PAS
- Message-ID: <1992Jul23.115908.57468@cc.usu.edu>
- Date: 23 Jul 92 11:59:07 MDT
- Organization: Utah State University
- Lines: 353
-
- {****************************************************************************
- *
- * This file implements just enough of a CP/M compatible file-system to
- * create files in a disk image of a ROM. In particular, it supports only
- * the following operations:
- *
- * - Make File
- * - Write Sequential
- * - Close File
- *
- * These routines assume that they can call:
- *
- * - ReadRom( Block_Number : Integer, Var Buffer );
- * - WriteRom( Block_Number : Integer, Buffer );
- *
- * They also assume that Buffer_Type is predefined as a buffer that can be
- * written.
- *
- ***************************************************************************}
-
- Type
- FCB_Name = Array[ 0..10 ] of Char; { File name and extension }
- Allocation_Map = Array[ 0..15 ] of Byte;{ Disk allocation map }
- Memory_FCB = Record
- DRV : Byte; { Drive number; high bit writes a deleted FCB
- when closed. }
- NAME : FCB_Name; { File name and extension }
- EX : Byte; { Extent number }
- FIX : Byte; { Position of this FCB on disk; first FCB is #0 }
- CR : Byte; { Current record position; high nybble =
- index into DM, low nybble = record in that one }
- NR : Byte; { Number of records owned by this FCB }
- DM : Allocation_Map; { Disk allocation map }
- End;
-
- Disk_FCB = Record
- ET : Byte; { Entry type: $E5 = deleted file }
- NAME : FCB_Name; { File name and extension }
- EX : Byte; { Extent number }
- Reserved1,
- Reserved2 : Byte; { Reserved; not used }
- NR : Byte; { Number of records owned by this FCB }
- DM : Allocation_Map; { Disk allocation map }
- End;
-
- Const
- Vector_Valid : Boolean = False; { If true, Vector contains a valid
- representation of the owned clusters on
- the disk. }
-
- Var
- NumClusters : Byte; { Number of clusters on the drive. }
- FCBBuffer : Array [ 0..3 ] of Disk_FCB;
- Vector : Array [ 0..127 ] of Boolean; { Bit map for drive. }
-
- Procedure Zero_Directory( Blocks, FCBs : Integer );
- Label 1, 2, 999;
- Var Block : Integer;
- Begin
-
- 1:
- Vector_Valid := False;
- Block := 0;
- FillChar( FCBBuffer, 128, $E5 );
- FCBBuffer[ 0 ].Name[ 0 ] := Chr( $37 );
- FCBBuffer[ 0 ].Name[ 1 ] := Chr( Blocks shr 3 );
- FCBBuffer[ 0 ].DM[ 6 ] := FCBs;
- Goto 2;
-
- 2:
- Write_Rom( Block, FCBBuffer );
- FCBs := FCBs - 4;
- Block := Block + 1;
- If( FCBs > 0 ) Then Goto 2;
- Goto 999;
-
- 999:
- End;
-
- Procedure Get_FCB( Var FCB : Memory_FCB );
- Label 1, 2, 3, 4, 999;
- Var
- Block : Integer;
- FIX : Byte;
- Begin
-
- 1:
- Block := FCB.FIX shr 2;
- Read_ROM( Block, FCBBuffer );
- FIX := FCB.FIX and 3;
- If( FCBBuffer[ FIX ].ET = $E5 ) Then Goto 3;
- Goto 2;
-
- 2:
- FCB.DRV := FCB.DRV and $7f;
- Goto 4;
-
- 3:
- FCB.DRV := FCB.DRV or $80;
- Goto 4;
-
- 4:
- FCB.NAME := FCBBuffer[ FIX ].NAME;
- FCB.EX := FCBBuffer[ FIX ].EX;
- FCB.NR := FCBBuffer[ FIX ].NR;
- FCB.DM := FCBBuffer[ FIX ].DM;
- Goto 999;
-
- 999:
- End;
-
- Procedure Close_File( FCB : Memory_FCB );
- Label 1, 2, 3, 4, 999;
- Var
- Block : Integer;
- FIX : Byte;
- Begin
-
- 1:
- Block := FCB.FIX shr 2;
- Read_Rom( Block, FCBBuffer );
- FIX := FCB.FIX and 3;
- if( ( FCB.DRV and $80 ) <> 0 ) Then Goto 3;
- Goto 2;
-
- 2:
- FCBBuffer[ FIX ].ET := 0;
- Goto 4;
-
- 3:
- FCBBuffer[ FIX ].ET := $E5;
- Goto 4;
-
- 4:
- FCBBuffer[ FIX ].Reserved1 := 0;
- FCBBuffer[ FIX ].Reserved2 := 0;
- FCBBuffer[ FIX ].NAME := FCB.NAME;
- FCBBuffer[ FIX ].EX := FCB.EX;
- FCBBuffer[ FIX ].NR := FCB.NR;
- FCBBuffer[ FIX ].DM := FCB.DM;
- Write_Rom( Block, FCBBuffer );
- Goto 999;
-
- 999:
- End;
-
- Procedure Init_FCB( Var FCB : Memory_FCB );
- Begin
- FCB.DRV := FCB.DRV and $7f;
- FCB.FIX := 0;
- FCB.CR := 0;
- FCB.NR := 0;
- FillChar( FCB.DM, 16, 0 );
- End;
-
- Function Make_File( Var FCB : Memory_FCB ) : Boolean;
- Label 1, 2, 3, 4, 5, 6, 7, 999;
- Var
- FIX : Byte;
- Block : Integer;
- FCBs : Integer;
- Begin
-
- 1:
- Init_FCB( FCB );
- FIX := 1;
- Block := 0;
- Read_Rom( Block, FCBBuffer );
- FCBs := FCBBuffer[ 0 ].DM[ 6 ];
- Goto 2;
-
- 2:
- If( ( FIX and 3 ) = 0 ) Then Goto 3;
- Goto 4;
-
- 3:
- Block := Block + 1;
- Read_Rom( Block, FCBBuffer );
- Goto 4;
-
- 4:
- If( FCBBuffer[ FIX and 3 ].ET = $E5 ) Then Goto 5;
- Goto 6;
-
- 5:
- FCB.FIX := FIX;
- Close_File( FCB );
- Make_File := True;
- Goto 999;
-
- 6:
- FIX := FIX + 1;
- If( FIX < FCBs ) Then Goto 2;
- Goto 7;
-
- 7:
- Make_File := False;
- Goto 999;
-
- 999:
- End;
-
- Procedure Build_Vector;
- Label 1, 2, 3, 4, 5, 6, 7, 8, 9, 999;
- Var
- FIX : Byte;
- Block : Integer;
- FCBs : Byte;
- I, DMIX : Integer;
- Begin
-
- 1:
- FIX := 1;
- Block := 0;
- For I := 0 to 127 do
- Vector[ I ] := False;
- Read_Rom( Block, FCBBuffer );
- NumClusters := Ord( FCBBuffer[ 0 ].Name[ 1 ] );
- FCBs := FCBBuffer[ 0 ].DM[ 6 ];
- Goto 2;
-
- 2:
- If( ( FIX and 3 ) = 0 ) Then Goto 3;
- Goto 4;
-
- 3:
- Block := Block + 1;
- Read_Rom( Block, FCBBuffer );
- Goto 4;
-
- 4:
- If( FIX < FCBs ) Then Goto 6;
- Goto 5;
-
- 5:
- Vector[ 0 ] := True;
- Vector_Valid := True;
- Goto 999;
-
- 6:
- If( FCBBuffer[ FIX and 3 ].ET = $E5 ) Then Goto 9;
- Goto 7;
-
- 7:
- DMIX := 0;
- Goto 8;
-
- 8:
- Vector[ FCBBuffer[ FIX and 3 ].DM[ DMIX ] ] := True;
- DMIX := DMIX + 1;
- If( DMIX < 16 ) Then Goto 8;
- Goto 9;
-
- 9:
- FIX := FIX + 1;
- Goto 2;
-
- 999:
- End;
-
- Function Allocate( Var FCB: Memory_FCB ) : Boolean;
-
- Label 1, 2, 3, 4, 5, 6, 7, 999;
- Var
- CurCluster : Byte;
- Begin
-
- 1:
- If( Vector_Valid ) Then Goto 3;
- Goto 2;
-
- 2:
- Build_Vector;
- Goto 3;
-
- 3:
- CurCluster := 0;
- Goto 4;
-
- 4:
- If( Vector[ CurCluster ] ) Then Goto 5;
- Goto 6;
-
- 5:
- CurCluster := CurCluster + 1;
- If( CurCluster < NumClusters ) Then Goto 4;
- Goto 7;
-
- 6:
- FCB.DM[ FCB.CR shr 4 ] := CurCluster;
- Vector[ CurCluster ] := True;
- Allocate := True;
- Goto 999;
-
- 7:
- Allocate := False;
- Goto 999;
-
- 999:
- End;
-
- Function Write_Sequential( Var FCB : Memory_FCB; Var Buffer ) :
- Boolean;
-
- Label 1, 2, 3, 4, 5, 6, 7, 8, 999;
- Var
- Block : Integer;
- Begin
-
- 1:
- If( FCB.NR > 127 ) Then Goto 2;
- Goto 3;
-
- 2:
- Close_File( FCB );
- FCB.EX := FCB.EX + 1;
- If( Make_File( FCB ) ) Then Goto 3;
- Goto 7;
-
- 3:
- Block := FCB.DM[ FCB.CR SHR 4 ] * 8;
- If( Block = 0 ) Then Goto 4;
- Goto 5;
-
- 4:
- If( Allocate( FCB ) ) Then Goto 3;
- Goto 8;
-
- 5:
- Write_Rom( Block + ( FCB.CR and 7 ), Buffer );
- FCB.NR := FCB.NR + 1;
- FCB.CR := FCB.CR + 1;
- Write_Sequential := True;
- If( ( FCB.CR and 7 ) = 0 ) Then Goto 6;
- Goto 999;
-
- 6:
- FCB.CR := ( FCB.CR + $10 ) and $F0;
- Goto 999;
-
- 7:
- Writeln( '%Write_Sequential: Directory full.' );
- Write_Sequential := False;
- Goto 999;
-
- 8:
- Writeln( '%Write_Sequential: ROM full.' );
- Write_Sequential := False;
- Goto 999;
-
- 999:
- End;
-
-