🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: alt.msdos.programmer
4 messages
4 total messages Started by vincent Thu, 12 Nov 1992 14:55
my_tsr
#630
Author: vincent
Date: Thu, 12 Nov 1992 14:55
136 lines
4353 bytes
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.
Re: my_tsr
#632
Author: Azrak
Date: Thu, 12 Nov 1992 19:36
34 lines
2071 bytes
vincent@datmuc.UUCP (vincent) writes:

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

[Lot's of text and code deleted....]

>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.

In the very few TSRs I have written (all in assembly, I'm afraid), I
save ALL registers I use, especially segment registers, like DS.
I never made my own stack, but the TSRs I wrote were also of the clock
interrupt type, and did not perform stack intensive operations,
though I did PUSH a few registers, including DS.
I did set DS = CS  upon entering the clock interrupt so I could get at
my own data easier, just remember to save DS before assigning it.

If you wish, I will post one of my TSRs for you to look at, but remember
that it is completely in 8088 assembly, and I am not a CS major. The
program might not be as efficient as possible, however it is quite
stable and will not crash very easily.

- Brian  (smithbm@craft.camp.clarkson.edu)

As for my opinion for why it crashes, try saving all registers used
in the interrupt routine. At least you will be at a "known state" and
can go from there. Just remember to POP all registers in reverse order
at the end of your routine.
Re: my_tsr
#771
Author: chris brennan
Date: Wed, 18 Nov 1992 02:50
28 lines
1744 bytes
In article <smithbm.721597007@craft.camp.clarkson.edu>, smithbm@craft.camp.clarkson.edu (Azrak) writes:
> 
> vincent@datmuc.UUCP (vincent) writes:
> 

> If you wish, I will post one of my TSRs for you to look at, but remember
> that it is completely in 8088 assembly, and I am not a CS major. The
> program might not be as efficient as possible, however it is quite
> stable and will not crash very easily.
> 
> - Brian  (smithbm@craft.camp.clarkson.edu)
> 
> As for my opinion for why it crashes, try saving all registers used
> in the interrupt routine. At least you will be at a "known state" and
> can go from there. Just remember to POP all registers in reverse order
> at the end of your routine.
> 
Hi Brian, 

your actual code was deleted when i read this article, but a frequent
problem which arises when writing tsr's is using DOS calls.

Dos is NON re-enterant. so you can not use calls to dos without first checking
the 'inDos' flag.  If Dos is busy and you still make a call, it will result in a 
corrupted stack and the system will crash.

-Bye Chris.  
 email: c.brennan@student.utas.edu.au.
Re: my_tsr
#776
Author: Azrak
Date: Wed, 18 Nov 1992 14:26
41 lines
2317 bytes
c.brennan@student.utas.edu.au (chris brennan) writes:

>In article <smithbm.721597007@craft.camp.clarkson.edu>, smithbm@craft.camp.clarkson.edu (Azrak) writes:
>> 
>> vincent@datmuc.UUCP (vincent) writes:
>> 

>> If you wish, I will post one of my TSRs for you to look at, but remember
>> that it is completely in 8088 assembly, and I am not a CS major. The
>> program might not be as efficient as possible, however it is quite
>> stable and will not crash very easily.
>> 
>> - Brian  (smithbm@craft.camp.clarkson.edu)
>> 
>> As for my opinion for why it crashes, try saving all registers used
>> in the interrupt routine. At least you will be at a "known state" and
>> can go from there. Just remember to POP all registers in reverse order
>> at the end of your routine.
>> 
>Hi Brian, 

>your actual code was deleted when i read this article, but a frequent
>problem which arises when writing tsr's is using DOS calls.

>Dos is NON re-enterant. so you can not use calls to dos without first checking
>the 'inDos' flag.  If Dos is busy and you still make a call, it will result in a 
>corrupted stack and the system will crash.

>-Bye Chris.  
> email: c.brennan@student.utas.edu.au.

Hmmm. People are getting confused about who had the trouble. It was
vincent@datmuc.UUCP that had the trouble. I tried to explain what I
thought the trouble was, and offered to post an assembly TSR. I don't
believe Vincent was using DOS inside the TSR. Like you say, it is bad news
to do so. I think his trouble was the fact that he wasn't saving the DS
register and possibly others, which were being modified inside the called
TSR routine (which hooked the timer INT). With TSRs, if you touch it, you
save it first!

- Brian
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads