Xref: utzoo alt.msdos.programmer:452 alt.sources:1089 comp.sys.ibm.pc:35570
Path: utzoo!attcan!uunet!ginosko!gem.mps.ohio-state.edu!apple!sun-barr!newstop!texsun!rpp386!aubrey
From: aubrey@rpp386.cactus.org (Aubrey McIntosh)
Newsgroups: alt.msdos.programmer,alt.sources,comp.sys.ibm.pc
Subject: Test MS-DOS file truncate, worry with 'lds si,[bp].n'
Summary: Success. Enjoy!
Keywords: MS-DOS; Duplicate file handle; Truncate file; LDS SI, label.
Message-ID: <17086@rpp386.cactus.org>
Date: 1 Oct 89 17:35:27 GMT
Reply-To: aubrey@rpp386.UUCP (Aubrey McIntosh)
Followup-To: alt.sources.d
Organization: Big "D" Home for Wayward Hackers
Lines: 302

I wrote the attached model program to answer questions for myself.  It is
not well commented, but possibly worth posting anyway.  At another time,
I might wear my editor hat, and clean up (someone elses) code so that it
reads better.  If anyone wants to edit this code (in the publishing sense)
please do so.  Naturally, you woud still attribute me as author.

Two threads of thought are explored and affirmatively answered in the program:
  1)  Can I truncate an existing file to an arbitrary length?
  1.a) Can I force MS-DOS to relinquish the disk space while the
       file is still open.
       
  2)  Can I construct any supporting environment for the 
         LDS SI, DWORD PTR label 
      instruction.
      
There are comments on the enter/leave macro.  If you have a NEC V20,
or '186, '286..., they produce correct code for those opcodes.  I was
arguing with MASM and found an opcode map before I found the MASM docs.
The familiar push bp/sub sp,/mov bp,sp sequence given as comments
in the macro is code suitable on an 8088 machine, in this one program.
They do not reconcile with the db statements in the macro.

I used Symdeb when exploring, and traced through the program.  At various
times, I would do a t= and, in effect, have a menu driven
interface through Symdeb.  Some of the comments [ only | can't otherwise 
possibly ] make sense unless you keep that in mind.  That is also why there
are Publics in a self-contained main level program.

CUT CUT CUT CUT CUT CUT CUT CUT CUT CUT CUT CUT CUT
CUT CUT CUT CUT CUT CUT CUT CUT CUT CUT CUT CUT CUT

	name	Truncate
	title	The File Truncate test program.  Verified w/ Symdeb.
	subttl  A style ancillary to LDS dx,mem.
	page	132,75
	.radix 16
;	.286
	
; --------------------------------------------------------
;	Aubrey McIntosh
;	Verify a method of truncating a file in MS-DOS.
;	September 19, 1989.  For use with Lilith emulator.
;	Modify or comment upon freely.  Leave my credits.
;
;	MD-DOS functions:
;	dos	3d02, 
;	dos	4200, 
;	dos	4000, 
;	dos	4000, 
;	dos	4500, 
;	dos	3e00, 
;	dos	3f00, 
;
;       I had needed a way to 'clip' a file at some point, so
;	that I could emulate the way a mag tape works, i.e.
;	when you write on it, and then 'rewind' it, there is
;	a file mark immediately past the last data, and earlier
;	files are irrelevant (erased).  Simply using create on
;	a new file was not useful to the third party application.
;
;	Misinformation has been on the net that this is not
;	possible, and I had tedious work arounds for years.
;	Here is how I did it.
;
;	Also, I digress into a shallow '86 hack.
; --------------------------------------------------------

data	group vars, stack		;no initialized values.
text	group const, code		;can be in rom.


public  stklimit, stk, filenm, handle, buffer
public	start, open, position0, trunc, 
public	position1, dupHandle, close0, read, close, stop
; --------------------------------------------------------



const	segment public para	'rom'
;	------  Various string and pointer constants.
filenm		db	'scratch.tmp',0
nameptr 	dd	filenm
bufptr		dd	buffer
stklimit	dd	stk
const	ends


vars	segment	public para	'ram'
handle	dw	?
buffer	db 100 dup ( ? )
vars	ends


stack	segment stack page	'ram'
	db 40 dup ('stack   ')
stk	label	word
stack	ends


; --------------------------------------------------------
;  The dos macro is just playing.  I was miffed about having to put all
;  the message addresses, lengths, and such somewhere before giving
;  each error message.  I thought LDS dx,xx would be a part of the solution,
;  but the setup seemed unusually expensive.  I worried with it a while,
;  and came up with this.  I sometimes still try to write tight code, just
;  to keep up an anachronistic skill.  Not a deep hack, but still an
;  unorthodox way of using the instruction set to get to the goal, and
;  an afternoon's pleasure.
;
;  The routine messageToAux uses the return address on the stack as
;  a pointer to a data packet immediately following the client's call.
;  This lets me use an LDS dx,[bp].2 instruction without
;  hardcoding pointers.
;
;  The string length, the correct return address, and the string
;  address are all implied by the packet, and are free with the
;  (far) return value on the stack!
;
;  This usage of [bp].n, IMHO, nicely compliments the LDS ,
;  instruction.  After much searching, it is the only method I know
;  to set up for the LDS without eating up memory with 
;  ptr dd