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,
;Pata_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.