Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!apple!usc!sdsu!ucsdhub!hp-sdd!ncr-sd!ncrlnk!ncrwic!encad!enprt!gharring From: gharring@enprt.Wichita.NCR.COM (Gary Harrington) Newsgroups: comp.sys.ibm.pc Subject: Re: Dos File Access In TSR's Summary: Some TSR file I/O insight Keywords: TSR DOS Message-ID: <491@enprt.Wichita.NCR.COM> Date: 22 Jun 89 18:15:26 GMT References: <157@wbcs.UUCP> Reply-To: gharring@enprt.UUCP (Gary Harrington) Organization: NCR Corporation, Wichita KS Lines: 100 In article <157@wbcs.UUCP> chris@wbcs.UUCP (Chris Rott) writes: >I want to write a TSR program that periodically wakes up and accesses a file >(using DOS Services). To allow a TSR program to operate safely (and even do file I/O) without having to worry about DOS re-entrancy problems, several undocumented features of DOS can be used. These undocumented DOS features are: 1. The COMMAND.COM Background Task: INT 28h is called by COMMAND.COM while it is waiting for input from the keyboard. During this time, the "In-DOS" flag (explained below) will be non-zero, but you can make DOS calls safely. 2. The "In-DOS" flag: A far pointer to this byte is returned in ES:BX by function 34h of INT 21h. The byte is non-zero whenever the processor is executing code within DOS, and implies that you should not try to invoke DOS (re-entrantly) at the moment (except via INT 28h). 3. Get Current PSP: The paragraph address of the current PSP is returned in BX by function 51h of INT 21h. 4. Set Current PSP: You can switch to another PSP by loading BX with the paragraph address of the new PSP and executing function 50h of INT 21h. Note that (3) and (4) above are required for DOS to maintain certain information in the PSP of the running program that relates to files - more specifically file handles. Some of the Essential Elements of a TSR that wants to do file I/O are: ---------- Before Terminating and Staying Resident, it should intercept three system interrupts by installing its own interrupt vectors and code for these interrupts: INT 13h - the BIOS disk I/O interrupt INT 1Ch - the system timer tick interrupt INT 28h - the Background Task interrupt ---------- Some of the TSR's program code might go something like this: ==================== | TSR Wake-Up routine +------------------- | save current stack | switch to your own stack | save all registers | save current PSP (use INT 21h func 51h to get current PSP) | establish (set) your own PSP (use INT 21h func 50h) | [do whatever processing you have to do] | if you need to do file I/O, then: | set an I/O_REQUEST flag | continue processing until you require the I/O to be done | wait until the I/O_REQUEST flag has been reset | restore the old PSP (INT 21h func 50h) | restore the old registers | restore the old stack | IRET | +=================== | New INT 13h Interrupt (disk I/O) +------------------- | set DISK_BUSY flag to BUSY | call the original INT 13 | set DISK_BUSY flag to NOT_BUSY | +=================== | New INT 1Ch Interrupt (timer tick) +------------------- | IF the I/O_REQUEST flag is set, and | IF the DISK_BUSY flag indicates disk is NOT_BUSY, and | IF DOS is not in a critical handling section, | THEN do the file I/O (and reset the I/O REQUEST flag) | call the original INT 1C | +=================== | New INT 28h Interrupt (Background Task) +------------------- | IF the I/O_REQUEST flag is set | THEN do the file I/O (and reset the I/O REQUEST flag) | call the original INT 28 | ==================== And, of course, before doing the file I/O within INTs 1Ch and 28h, you would need to switch stacks, save registers, and set your own PSP. Not included here are the Critical Error (INT 24h), Ctrl-Break (INT 23h), and Terminate Address (stored in interrupt vector 22h) handlers which you may want to add for a more complete TSR implementation. Would any of you TSR experts care to change or fix any of the above? Gary.Harrington@ncrwic.UUCP (Wichita, Kansas)