Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

file truncation in CP/M 2.2?

194 views
Skip to first unread message

Bridger Mitchell

unread,
May 31, 1988, 8:17:52 PM5/31/88
to

Unlike CP/M Plus, CP/M 2.2 has no truncate-file function. This
is a useful function when a large file (e.g. a database or library file)
needs to be "lopped off", or packed down, and there's a lack of disk
space to create a temporary duplicate file.

Is there a portable method of truncating a CP/M 2.2 file, using only
BDOS calls? I believe the following approach will work so long as the
shorter file's final physical extent (i.e. directory entry) is the
same as the original file's:

open the file
get file size, to set extent, S2, and record count bytes
change record count to new number of records in final
logical extent
change extent number, if necessary, to new final logical
extent
clear bit 7 of S2, to mark the file/fcb "modified"
close the file
use function 37 to log off the drive (use the FRESET routine,
or function 13, if run on the buggy DRI BDOS).

The BDOS will write the changed fcb (directory entry) to the directory
when the file is closed, then rebuild the allocation vector for the
drive using the new number of records.

BUT...what can be done if the truncation results in eliminating the
last physical extent(s)? The BDOS internally opens and closes each
physical extent of a multi-extent file. Suppose, for example, you read
randomly the last record you wish to keep in the new file and it's
not in the last physical extent. Then you use the procedure above,
and the intermediate extent will be modified in the directory.

But the final extent will remain in the directory, unchanged. Disk
logins will continue to keep the data groups reserved in that entry
allocated; they are effectively stranded. And directory utilities
that sort extents will be badly confused. You'd like to "erase" just
that final extent. But this can't be done by BDOS calls. Or can it?

-- bridger mitchell

David Goodenough

unread,
Jun 2, 1988, 10:25:49 AM6/2/88
to
From article <880601001...@newton.arpa>, by bridger%new...@RAND-UNIX.ARPA (Bridger Mitchell):

>
> Unlike CP/M Plus, CP/M 2.2 has no truncate-file function. This
> is a useful function when a large file (e.g. a database or library file)
> needs to be "lopped off", or packed down, and there's a lack of disk
> space to create a temporary duplicate file.
>
> Is there a portable method of truncating a CP/M 2.2 file, using only
> BDOS calls?

[description of how to do it]

Yes - changing the file size (.fcb + 0fh) will do what you want - this is
how xsub works.

> BUT...what can be done if the truncation results in eliminating the
> last physical extent(s)?

> ..... But this can't be done by BDOS calls. Or can it?

No it can't. but it CAN be done portably with BIOS calls. By inspecting
the bios tables (use the "get dpb address" function from bdos) you can
figure out exactly where the directory is, and how big it is. Now keep
on reading directory sectors using bios till you hit the one with the
extent that you want to nuke. Now just replace the first byte in the 32
byte entry with 0e5h, write it back (see caveat) and voila!
CAVEAT: whatever you do, when you write this sector back, reuse the
bios select disk, track, and sector routines, AND MAKE SURE C CONTAINS 1.
At least one bios I've seen destroys the track/sector info on each
read/write, so it's a good idea to reset them. Setting C to 1 forces
the write to happen: usually on bioses where the sector size is
greater than 128 bytes (i.e. all 5.25" DD versions) when a write happens,
the data is just buffered, and only gets flushed when another write to a
different sector occurs. By making C == 1, it forces the bios to write,
hence the directory is kept up to date.

Easy Huh? :-) :-)
--
d...@lakart.UUCP - David Goodenough +---+
| +-+-+
....... !harvard!adelie!cfisun!lakart!dg +-+-+ |
+---+

dxf...@gmail.com

unread,
Nov 6, 2017, 7:11:57 PM11/6/17
to
This is an ancient thread but does anyone know
if the technique suggested was ever implemented?
The Computer Journal had a routine that let you
determine free disk space under CP/M 2 or 3 but
I've never seen anything for file truncation
other than the two intriguing posts above.

Udo Munk

unread,
Nov 9, 2017, 3:55:31 PM11/9/17
to
On Tuesday, November 7, 2017 at 1:11:57 AM UTC+1, dxf...@gmail.com wrote:

> This is an ancient thread but does anyone know
> if the technique suggested was ever implemented?
> The Computer Journal had a routine that let you
> determine free disk space under CP/M 2 or 3 but
> I've never seen anything for file truncation
> other than the two intriguing posts above.

I do remember that we fiddled with ftrunc() for some C compiler,
which was implemented without copying the file. For that it had
to manipulate the directory in some way via the BIOS, can't remember
details anymore, sorry. Probably that was MI C or Aztec C, I didn't
do much with the other ones.

dxf...@gmail.com

unread,
Nov 10, 2017, 10:48:43 AM11/10/17
to
Searching the CP/M cdrom I found CUT10.LBR.
It's a file splitter but it does it by reading/
writing the disk directory. It's close to what
I need and the asm source will give me a good
start.

dxf...@gmail.com

unread,
Nov 11, 2017, 12:54:09 AM11/11/17
to
Looking at the source for CUT I was impressed by
the simplicity of it. This is primarily due to
the use of BDOS search first/next to grab the
directory sectors. If any is changed it then uses
BIOS WRITE to update the disk.

But this assumes BIOS is still set to the same
track/sector/buffer when BDOS called it to
read the dir sector. According to the second
post in this thread, with some BIOS this is not
guaranteed. Does anyone have an opinion on this?
I'd prefer not to complicate my code if we're
talking only a few bios.

Udo Munk

unread,
Nov 11, 2017, 6:09:39 AM11/11/17
to
On Saturday, November 11, 2017 at 6:54:09 AM UTC+1, dxf...@gmail.com wrote:

> Looking at the source for CUT I was impressed by
> the simplicity of it. This is primarily due to
> the use of BDOS search first/next to grab the
> directory sectors. If any is changed it then uses
> BIOS WRITE to update the disk.
>
> But this assumes BIOS is still set to the same
> track/sector/buffer when BDOS called it to
> read the dir sector. According to the second
> post in this thread, with some BIOS this is not
> guaranteed. Does anyone have an opinion on this?
> I'd prefer not to complicate my code if we're
> talking only a few bios.

A BIOS that would read ahead, like buffering a whole track,
might not be set to the same sector/track anymore, after
reading one. But this could easily be fixed in the BIOS, if
necessary. So I would not complicate the code for such
situations, but fix the BIOS.

Floppy Software

unread,
Nov 11, 2017, 6:20:34 AM11/11/17
to
IMHO using the CP/M BIOS disk i/o functions are always a source of unexpected problems.

BIOS implementations have different internal behaviours to do the same thing and if compatibily is important for you, you should take into account how CP/M 3 BIOS disk i/o functions differ with the CP/M 2 ones.

As you know, the risk of corrupting the disk data is high.

j...@mdfs.net

unread,
Nov 11, 2017, 11:31:42 AM11/11/17
to
Udo Munk wrote:
> So I would not complicate the code for such situations, but
> fix the BIOS.

What if that's not possible? "Here is some software I've written,
but for you to use it I need to come around your house and take
the lid off your computer and change some ROMs."

Udo Munk

unread,
Nov 11, 2017, 12:06:21 PM11/11/17
to
Sure, but nowadays it is fix your ROM's self ;-)
You might not be able to work around all and any BIOS anyway.

dxf...@gmail.com

unread,
Nov 11, 2017, 9:01:08 PM11/11/17
to
Yes. Though for my purposes (file truncation) the
code will only be invoked if CP/M 2 is sensed.
CP/M 3 already has a bdos function for
truncation.

Under 2.2, there should be little need for the
bios to mess with the track/sector/buffer
parameters it has been passed since it is only
required to deliver one 128 byte record.

Speaking of disk corruption, CUT10.LBR appears
to have a serious bug. The extent renumbering
assumes each disk fcb holds no more than 16K
of data and when the dir is read, the extents are
all in numerical sequence. OTOH the program is
very well documented :)
0 new messages