From: vincent@datmuc.UUCP (vincent)
Newsgroups: alt.msdos.programmer,comp.os.msdos.programmer
Subject: my_tsr
Date: 12 Nov 92 14:55:04 GMT
Followup-To: alt.msdos.programmer,comp.os.msdos.programmer

This is a (re)repost I never got any replys, The Org. Q. was why this code
doesn't work?

Some people on the net said that it was uncommented (correct I comment
finish projects so my boss is happy). As to what the code does. Here we go.

I forge this sample tsr from the examples in Andrew Schulman's book
'Undocumented DOS':

The main part allocated a stack, frees the envirement, get and set the timer
interrupt, calculates the size of the tsr, shrink the program block accordingnly
and then go tsr.

The tsr should pop up durring timer interrupt, save forground stack and data
segment, set our stack and data segement, make base pointer relative to the
stack pointer, call the timer function (now only increments variable),
on return from it reset the stack and the data segment and then chain
the interrupt.

All data are in the code segment (for futur migth be a .COM file)

The compile flags turns off stack check, disable optimisation, use small
memory model, ... (maybe need to put #pragma (check_pointer off)

---------------------  snip snip -------------------------- makefile

CFLAGS = /Fc /Zi /f /Od /Gs /AS /W4 /nologo

main.exe : main.obj
	cl /Zi /Fm main.obj

.c.obj:
	cl /c $(CFLAGS) $(@B).c

---------------------  snip snip --------------------------- main.c

#include	<stdlib.h>
#include	<dos.h>
#include	<bios.h>

#define	CODESEG			_based(_segname("_CODE"))
#define MK_FP(seg,ofs)		((void _far *) ((((long)seg)<<16) + (long)ofs))
#define PARAGRAPHS(x)		((FP_OFF(x) + 15) >> 4)

typedef			void	(interrupt _far *INTVECT) ();

struct {
	INTVECT	old_timer;

	unsigned char _far * CODESEG tsrstack;

	int	oldSP,
		oldSS,
		oldDS,
		ds_save,
		seg_stack,
		off_stack,
		retadd,
		tick_me;
} CODESEG data;

void ctimer (void)
{
	data. tick_me++;
}

void _interrupt _far new_timer (void)
{
	_asm {
		mov	cs:data. oldSS, ss	; save forground stuff
		mov	cs:data. oldSP, sp
		mov	cs:data. oldDS, ds
				 		 ; Load new stack
		mov	ss, cs:data. seg_stack
		mov	sp, cs:data. off_stack
		mov	ds, cs:data. ds_save

		mov	bp, sp			; make bp relative to sp
						; why? I don't know

		call	ctimer			; do some proccessing

		mov	ss, cs:data. oldSS	; restore the forground stuff
		mov	sp, cs:data. oldSP
		mov	ds, cs:data. oldDS

		mov	bp, sp
	}
	_chain_intr (data. old_timer);		; jump to old function
}

void main ()
{
	unsigned int memtop, dumy = 0;

	data. tick_me = 0;				// init. variables

							// free envirement
	_dos_freemem (*(short _far *) MK_FP (_psp, 0x2c));

							// allocate a stack
	data. tsrstack = malloc (1024);
	data. tsrstack += 1024;				// go to the top of it

	data. seg_stack = FP_SEG (data. tsrstack);	// save the segment and
	data. off_stack = FP_OFF (data. tsrstack);	// the offset for latter

	_asm mov cs:data. ds_save, ds			// save the data segment

							// calculate the size
	memtop = data. ds_save + PARAGRAPHS (data. tsrstack) - _psp;

	_dos_setblock (memtop, _psp, &dumy);		// shrink the prog.

	data. old_timer = _dos_getvect (0x08);		// get and set the timer
	_dos_setvect (0x08, new_timer);			// interrupt

	_dos_keep (0, memtop);				// go tsr
}

---------------------------------------------------------------------

vincent@datmuc.dat.de

P.S. Well I hope this is better documented (my boss would be happy)

P.P.S. The problem is that on return to DOS (COMMAND) sucessive program
crash (window for example);

P.P.P.S. I will continue on my side like instead of allocating a stack,
have a fix buffer in the code segment. Also to date I'm not shure
if I need to save the DS since it is anyway restore at the interrupt.
Also in the inline asembly I might try to set ds to cs (for my data) and
also for the stack seg.. (I guess I do need my own stack). The only thing I know
about .COM is that LINK tell me that for tiny memory model I am not alowed
to have _far pointers.
Xref: sparky alt.msdos.programmer:2709 comp.os.msdos.programmer:10502