PDA

View Full Version : How do I create a dummy file entry with a specific length?



Ken Vaughn
February 21st, 2011, 03:05 PM
I have an old IMSAI with Northstar disk drives on which I run
Northstar DOS 5.x and CP/M 2.2, both in double density. I need to
transfer both text and binary files back and forth between the two
operating systems. I do this with a "special" diskette, which is
formatted as single density to avoid interlaced sector problems in CP/M.

Both OS's have the ability to read/write single density files.
This disk has two directories (catalogs) --a N* directory with a
single file pointing to the start of the CP/M file data area. There
is also a CP/M directory with a single file which points to the same
track and sector as the N* file. Trust me -- this works -- I have
been doing this for years.

N* DOS, being more primitive than CP/M, allows me to define a file
entry with any length that I desire. Under CP/M, I erase the previous
file entry and create a new one with the following:

SAVE n U:Filename.Typ
(where n is the nbr of pages=256 byte blocks)

OK, here's the problem. If I need to create a file entry under CP/M
with a length greater than what the CP/M SAVE command allows (length
of TPA), how do I do this?

SteveH
February 22nd, 2011, 04:28 AM
You could try something like this...

1. Using the SAVE command, first create a file of known size.
2. Use PIP to create a new file that contains multiple copies of the file created in step 1

e.g.

SAVE 128 U:SIZE128.FIL
PIP U:SIZE256.FIL=U:SIZE128.FIL,SIZE128.FIL

FloppySoftware
February 22nd, 2011, 04:48 AM
Hi, Ken!

You can create a little program in assembler, basic, c... to create a file with 'x' 128 bytes records in size.

Ken Vaughn
February 22nd, 2011, 06:33 AM
Thanks to SteveH and FloppySoftware for their replies. I also asked this question on the newsgroup "comp.os.cpm". I got similar replies there also. I further responded to that forum: (cut and paste)

Thanks for your reply. I believe that I may not have asked my
question properly. I was trying to determine if I was overlooking
some simple way to create a directory entry (without copying a file)
-- perhaps even an undocumented trick.

I have only needed to create such a large file entry a few times. For
the most part, the files that I need to move from DOS to CP/M are
small and the SAVE command allows me to quickly and easily create a
dummy file entry of the proper size. The SAVE command does not create
the file -- I use it only to create a properly sized file entry in the
CP/M directory. The few times that I have needed a larger file entry,
I have been using a CP/M editor (VEDIT) to append records until I
create a temporary file large enough to copy to my DOS/CPM transfer
diskette, thus creating a sufficiently large file entry in the CP/M
directory. The content of the temporary file is not important -- it
gets overlaid immediately when I transfer the DOS file (using the
Northstar DOS copy file command) because both file entries point to
the same starting disk address. The file creation and copy imposes an
extra step in the process.


It would be a simple matter to write a program in assembly language to
create the temporary file. I frequently program in assembly
language. The program would pass the number of pages to be written on
the command line. Although I am not sure that I will need this tool a
lot, I will probably go ahead and write such a program.

Chuck(G)
February 22nd, 2011, 08:50 AM
Well, yes, it's possible to directly create directory entry/entries, but once the file passes about 16K in size, it gets a little more complicated because it takes multiple directory entries to describe larger files. On the plus side, all you need to is create directory entries with the proper allocation units filled in--unlike DOS, there's no separate allocation tracking mechanism--everything's in the root directory. You must physically "touch" each allocation block in the file with a write to get a single fully-allocated large file.

Hope this helps.

If you think that you can simply create a file, then perform a "normal" random write at the end of the file, then close the file (as one might do under MS-DOS), it won't work. You'll have a large file, all right, but it will be a "sparse" file--allocation units won't be filled in and extents will be missing. This is a "feature" of CP/M, that files with little actual data require very little space. Fortunately, there is a BDOS command--function 40--"Write Random with zero fill" that will allocate and write the entire file area.

Ken Vaughn
February 22nd, 2011, 12:26 PM
If you think that you can simply create a file, then perform a "normal" random write at the end of the file, then close the file (as one might do under MS-DOS), it won't work. You'll have a large file, all right, but it will be a "sparse" file--allocation units won't be filled in and extents will be missing. This is a "feature" of CP/M, that files with little actual data require very little space. Fortunately, there is a BDOS command--function 40--"Write Random with zero fill" that will allocate and write the entire file area.

Thanks Chuck -- I was aware of the extents issue, but hadn't thought about the "sparse" file problem. I'll look into the #40 function, might be able to cobble up something using that.

It's only an issue with binary files. For text files I just copy into a maximum size pre-allocated DOS file using a copy to eof utility. PIP copies until it encounters a Ctrl-Z eof byte, and I have a simple utility on the DOS side which does the same and adds the CP/M eof byte if needed. This utility also converts the single density CP/M file back to double density on the DOS side. Most of the files that I have been transferring are assembly language source files and therefore are text.