shaunc@gold.gvg.tek.com (Shaun Case) (06/18/91)
Hello helpful netters! Last week you may have seen a post from me asking about XMS memory handles. I wanted to know if they are limited to any particular range, so I could speed up a search through all of them, or at least set an upper bound on the time it would take. I received two replies, both which indicated that XMS handle numbers are implementation dependent. One source also indicated that EMS handles may be as well. It seems to be time to ask again, with more information. I think this will be of general interest to many people here, if not now, then some time in the future. (I could be wrong, of course. Read at your own risk. :-) I use a number of programs that don't restore the screen when they exit. I want to fix this. Right now, I have a program that runs, saves the text screen to a disk file, then exits. Then, the main application is run. After it exits, my program runs again, restoring the text screen and cursor position from the disk file. This is all fine and dandy, and I even released it (in the public domain.) However, if you don't have a ramdisk, or a fast hard disk, then there is a noticeable delay between the main application exit and the screen restore. I recently got copies of some excellent EMS and XMS libraries for Turbo/Borland C by James Birdsall. (Registration forthcoming, pending successful completion of this problem, if you're listening, James!) Everything in the libraries works fine. My problem is that one my program exits and then reloads, it doesn't know which EMS or XMS handle it was using! My solution now is: EMS: Require 4.0 or above, and use the name setting feature to indicate page ownership by my program. XMS: Copy the same string into the first n bytes of the 1st page, thus doing a kludgy version of the EMS setname. For both types, my program starts scanning handles at 0 through whatever is necessary to support 16 MB, search for valid handles, and looking for the names whenever it finds a valid handle. To me, this appears really stupid, and if handle numbers are implementation dependent, possibly much too slow. Bogosity. My other possible solution was to set an environment variable like SET MYPROG=NNNNNNNNNN, and then sprintf() in an E or an X for the memory type, and then the handle number. Of course, this requires modifying the master environment, which, according to all accounts, is a rough thing to do. Neverthless, I gave it a shot and failed; TASM/ TC code is below, for anyone who wants to try to fix it. (I didn't write the ASM code, I swiped it from Simtel.) Anyhow, does anyone have a good idea about how (or where) I can store 17 bits without going to disk? This really has me stumped. Any and all solutions appreciated. Email or posting is fine, I do both. Shaun. The program below generates 'Abnormal program termination' in the .asm module. --- cur here for main.c --- #include <stdio.h> #include <dos.h> extern char *FE(short psp); int main() { char *start; start = FE(_psp); while (*start != NULL) { puts(start); start += strlen(start); } return 0; } --- cut here for me.asm --- .MODEL small .STACK 100h .DATA .CODE ; ;========== ;tech.notes/pc.code #29, from pmaupin, 3407 chars, Sat Jun 4 22:40:45 1988 ;---------- ;TITLE: Finding DOS's master environment pointer ;This is a fragment of code that my SD.COM program uses to find ;the environment. This fragment is different than most ways of ;finding the environment, in that it finds the MASTER environment block, ;not the current process's parent's environment. ; ;This is useful in some cases, and has the added advantage that ;it does NOT behave differently when executing under CodeView, ;so you do NOT have to hard-code your system's DOS environment address ;into your program in order to debug it. EnvPtr EQU 2CH ; Offset in PSP CommandInterrupt EQU 2EH ; entry point into first Command.Com ; through interpreter DosSegPtr EQU CommandInterrupt * 4 + 2 ; FindEnvironment is passed: ; DS should point to program PSP ; FindEnvironment returns: ; ES points to master environment block, or program's copy if couldn't ; find the master. ; CX is length of block, or 0 if couldn't find the master. ; FindEnvironment destroys: ; AX, SI PUBLIC C FE FE PROC C NEAR psp: WORD mov ds, psp xor si,si ; Point to segment 0 mov es,si mov si, word ptr es:[DosSegPtr] mov ax,si call VerifyBlock ; make sure we've found COMMAND jnz GotBlock ; jump if not a good block -- ; use process's environment mov ax,es:[EnvPtr+10h] ; get COMMAND's environment ptr or ax,ax ; jump if COMMAND has a jnz MaybeGoodBlock ; subsidiary environment mov ax,si ; If no subsidiary, just use add ax,cx ; the allocation block inc ax ; immediately after COMMAND MaybeGoodBlock: call VerifyBlock ; verify that we have a good ; one, one way or another GotBlock: shl cx,1 ; multiply by 16 to get shl cx,1 ; length in bytes shl cx,1 shl cx,1 mov es,ax ret ; VerifyBlock tries to insure that we're pointing to a valid DOS ; allocation block. If not, returns the current process's environment ; block. VerifyBlock PROC C NEAR dec ax ; get block header into ES mov es,ax inc ax cmp byte ptr es:[0],04Dh ; make sure signature is valid jnz UseCurrent cmp word ptr es:[1],si ; make sure owner is valid jnz UseCurrent mov cx, word ptr es:[3] ; retrieve the length ret UseCurrent: mov ax,word ptr ds:[EnvPtr] ; get current process's env xor cx,cx ; zero length ret VerifyBlock ENDP FE ENDP END ; ;So far, this seems to work. I would welcome any feedback on its ;efficacy, but if the feedback is negative, please give the DOS version ;and a detailed problem description. Thanks, ;Pat
a_rubin@dsg4.dse.beckman.com (Arthur Rubin) (06/22/91)
In <2556@gold.gvg.tek.com> shaunc@gold.gvg.tek.com (Shaun Case) writes: >Hello helpful netters! >Anyhow, does anyone have a good idea about how (or where) I can >store 17 bits without going to disk? This really has me stumped. According to MEMORY.LST, attributed to Robin Walker in Ralf Brown's interrupt lists, memory addresses 40:F0-FF are reserved to the user. If nothing else around uses them, that should do what you are looking for. -- 2165888@mcimail.com 70707.453@compuserve.com arthur@pnet01.cts.com (personal) a_rubin@dsg4.dse.beckman.com (work) My opinions are my own, and do not represent those of my employer.