Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!seismo!lll-lcc!rutgers!husc6!mit-eddie!interlan!backman
From: backman@interlan.UUCP (Larry Backman)
Newsgroups: comp.sys.ibm.pc
Subject: Re: Dos Calls and Interrupts
Message-ID: <115@interlan.UUCP>
Date: Mon, 12-Jan-87 07:31:50 EST
Article-I.D.: interlan.115
Posted: Mon Jan 12 07:31:50 1987
Date-Received: Mon, 12-Jan-87 21:51:14 EST
References: <216700005@orstcs.UUCP>
Reply-To: backman@interlan.UUCP (1014-Larry Backman)
Organization: MICOM-Interlan, Boxborough, MA
Lines: 86
Keywords: TSR, DOS Re-entrancy

In article <216700005@orstcs.UUCP> mjbo@orstcs.UUCP (mjbo) writes:
>
>I have read in several places, including the most recent BIX
>section of Byte,  that it is not legal to call on DOS
>services from an interrupt-service routine.
>I would like to write a TSR program to hide in the
>background and receive data from a serial port using
>an interrupt routine to store the data in a buffer.
>When the buffer fills, I would like to store the
>data in a Hard-disk file dedicated to that purpose.
>(sort of a print spooler in reverse).  Can this be done
>safely?   If so, what restrictions are there on the
>DOS file-handling calls?   Can a foreground program
>read from the input spooler file  without messing 
>it up for the interrrupt service routine>
>

	Calling DOS from an ISR can be done safely; its tricky, and there
	are a number of things to be taken into account.  However, you must
	use undocumented DOS calls to do so.

	When an interrupt service routine is kicked off, there is no guarentee
	where your CS:IP and stack pointeres were before the interrupt occurred.
	For all you know, you may have interrupted DOS itself, possibly in the
	middle of a critical section of code.  As evryone knows, DOS is not a
	re-entrant operating system, it is singled threaded, and cannot handle
	concurrent system calls.  However, the folks in Bellevue still needed
	to be able to detremine when it was safe to do something within their
	own operating system thus the following two undocumented functions.

		1).   The "dirty bit".
			INT 21 function 34 returns the status of DOS's dirty
			bit indicating whether DOS is in a critical section.
			If AL returns with a 0, its safe to access DOS, if
			it returns non-zero, DOS cannot be safely interrupted.

		2).   The scheduler	
			INT 28 is the DOS scheduler interrupt.  When DOS is
			active but idle ( the keyboard scan loop for instance)
			it periodically issues an INT 28, allowing other 				sleeping processes a chance to run.  A resident program
			(such as PRINT or MODE) can grab this vector, and do its
			thing safely when scehduled by an INT 28.

	Thes two functions provide the hooks necessary to call DOS from an ISR.
	Needless to say your ISR must be tied to some sort of non-interrupt code
	which is capable of performing actions at a later time.

	Lets say your ISR captures an interrupt, has a full buffer and wants to
	write that buffer out to file.  First the ISR saves the state of the
	machine and switches the stack.  The stack switch is necessary since
	the DOS stack is only guarenteed to be 80 bytes deep, not enough for
	any serious processing especially if you intend to re-enter DOS!

	Once you have swapped stacks you may re-enable interrupts if you so
	desire.  Now comes the fun part!  Issue an INT 21 function 34; if it
	comes back with AL set to 0 your golden; do whatever you want right
	then and there!  If however, it comes back indicating that DOS is in
	a critical section you must then use the scheduler interrupt to do 
	your DOS access.

	So, when you started this program you undoubtabl did things like
	replacing interrupt vectors, well make sure you replace INT 28 with
	a function of your own.  Your printer interrupt handler should be
	able to share a semaphore with the INT 28 handler, so that when
	your printer handler is blocked from performing a DOS access, it
	sets this semaphore saves a pointer to the buffer cleans up after
	itself and IRETS.  Now next time DOS calls INT 28 our handler is 
	activated; it checks the semaphore and if it is set performs the DOS
	access that was previously blocked.  If the semaphore is not set, as
	should be the case 99% of the time, the INT 28 handler simply IRETS. 

	I hope this provides enough information to get you started, be warned
	that its tricky and a good debugger is a must.  I also suggest disassem-
	bling PRINT.COM to see how a Microsoft approved resident DOS access 
	works.  Feel free to call me if you need more information..


					Larry Backman
					Micom - Interlan, Inc.
					155 Swanson Rd
					Boxborough, Ma. 01719
					617-263-9929 x291

					ulowell!  -\
					mit-eddie!  -->  interlan!backman
					ihnp4!    -/