[comp.sys.atari.st.tech] How to use the VDI from the Autofolder

micro@imada.ou.dk (Klaus Pedersen) (05/25/91)

Hi, 

When I tried to make the code that installed the Trap#2 handler I found
that it was possible to use the vdi from the auto-folder, a thing that
I thought was impossible! The trick is to open a physical screen work-
station. Simple and clean...

Here is some code you can try out: (it only works in the autofolder, 'cause
it don't check if there already is one open! (aes's))


Klaus, micro@imada.ou.dk

(please let me know if you care about these things - I hate to send things
 into a big void)

-------- This was made using TurboC, but any compiler should do ---------
('int' is 16 bit)

#include <vdi.h>

static int pointer[] =
{0x0002, 0x0002, 0x0001, 0x0000, 0x0001, 
 0x7200, 0xAD00, 0xFE80, 0x6F78, 0xD808, 0x380C, 0x2002, 0x4001,
 0x4001, 0x8000, 0x8008, 0x4009, 0x4011, 0x2002, 0x1004, 0x0C18,
 0x0C00, 0x5200, 0x0100, 0x9080, 0x27F0, 0x07F0, 0x1FFC, 0x3FFE, 
 0x3FFE, 0x7FFF, 0x7FF7, 0x3FF6, 0x3FEE, 0x1FFC, 0x0FF8, 0x03E0};

static int work_in[] = {1,1,1,1,1,1,1,2,3,1,2};
/* fill pattern(black,checkboard), black full line */

int work_out[57];

main()
{int mx, my, mk, d;
 int hchar, wchar, hbox, wbox, handle, phys_handle;
 int pxy[8];
 
	work_in[0] = 1;
	v_opnwk(work_in,&phys_handle,work_out);

	work_in[0] = handle = phys_handle;
	v_opnvwk(work_in, &handle, work_out);

	vsc_form(handle, pointer);
	v_hide_c(handle);
	vswr_mode(handle, 1);
	vsf_perimeter(handle, 1);
		
	pxy[0] = 0;
	pxy[1] = 0;
	pxy[2] = work_out[0];
	pxy[3] = work_out[1];
	vr_recfl(handle, pxy);
	
	vsf_interior(handle,0);
	vst_point(handle,10,&hchar, &wchar, &wbox, &hbox);
	vst_alignment(handle,0,5,&d,&d);
	pxy[3] = hbox+2;
	v_bar(handle, pxy);
	v_gtext(handle,0,1,"   Desk  File  Edit ");
	
	vswr_mode(handle, 2);
	v_show_c(handle, 0);
	do
	{	vq_mouse(handle, &mk, &mx, &my);
		if (mk == 1)
		{	v_hide_c(handle);
			v_gtext(handle,mx,my,"test");
			v_show_c(handle, 1);
		}
	}
	while (mk != 2);
	v_hide_c(handle);
	
	v_clsvwk(handle);
  	v_clswk(phys_handle); 
	return 0;
}

entropy@gnu.ai.mit.edu (maximum entropy) (05/25/91)

In article <1991May24.184249.21414@imada.ou.dk> micro@imada.ou.dk (Klaus Pedersen) writes:

>When I tried to make the code that installed the Trap#2 handler I found
>that it was possible to use the vdi from the auto-folder, a thing that
>I thought was impossible! The trick is to open a physical screen work-
>station. Simple and clean...

> [...]
>	   v_opnwk(work_in,&phys_handle,work_out);
> [...]
>	   v_clswk(phys_handle); 
> [...]

Pardon me if I'm wrong, but everything I've ever read about the ST's
GEM (specifically the Abacus volume) has said "V_OPNWK AND V_CLSWK ARE
NOT IMPLEMENTED IN ATARI ST GEM" (OK, maybe they didn't use all caps
:-) Isn't this a really bad idea, especially when you've just flamed
someone for using undocumented variables in another posting?

Or does GEM use these these functions itself upon starting up?


--
			  entropy@gnu.ai.mit.edu
	entropy. . .it's not just a good idea, it's the second law.
     Boycott Lotus, Apple, Ashton-Tate and Xerox.  Join the League for
Programming Freedom!  Write to league@prep.ai.mit.edu for more information.

Roger.Sheppard@actrix.gen.nz (Roger Sheppard) (05/25/91)

This came from a File that I found some time back on Genie, it could
be of help to otheres, with the Trap #2 problems.

 ------------

Category 2,  Topic 19

Message 108       Sun Nov 13, 1988

C.F.JOHNSON                  at 16:19 PST

Steve,

  Stealing trap #2 is not quite as easy as Dan made it seem; you can use
his method (except for the "magic cookie"...more on that later) with all
the other trap vectors (1, 13, and 14), but intercepting trap #2 is
uniquely difficult because the operating system keeps replacing its own
address in the vector!  TOS seems to reset $88 (trap #2) every time
you runa .TOS or .TTP program, or show a file from the desktop.
 (And maybe at other times too...)

  After lots of thrashing around for methods to solve this thorny
problem, Bob Breum (Easel ST), Wayne Buckholdt (Turbo ST),
 John Eidsvoog (fellow CodeHead),

and I came up with a method of intercepting trap #2 "safely"...in
other words,

so that the system can't de-install you while you aren't looking, and
so that other programs which use the same method can coexist peacefully.

  The method is not exactly obvious....and that's why there are a lot of

programs (e.g. FSEL60) which don't get along with other programs that
need to steal trap #2.
  Some programmers, in order to keep their software working,

resorted to desperate measures...like checking the trap #2 vector every

vertical blank interrupt and just replacing their address if it ever
changed. 

This method does work, as long as your program is the only one that steals

trap #2 --- which is a ridiculous assumption to make, with more trap #2

thieving programs appearing every day.


We decided (all of the folks listed above) to publicize thisinformation as
widely as possible, in the hope that everybody's "GEM fixer-upper" programs
will be able to get along.
 The following section of assembly code illustrates the process,
 with lots of comments:

 **********************************
 *                                *
 *  Intercept the trap #2 vector  *
 *                                *
 *   Code by Charles F. Johnson   *
 *                                *
 **********************************

 * Last revision: 06/26/88  12:13:32

 * In order to steal trap #2 permanently, it's necessary to watch for a

 * certain BIOS call from the operating system - a setexec() call for the

 * critical error vector.  TOS issues this call after running a .TOS/.TTP

 * program, and immediately after changing the trap #2 vector at $88.  So

 * when this call comes through, you know it's time to re-steal trap #2.

 * Good luck, Jim.  We're all counting on you.



        .text



 * ------------------------

 *  Program initialization

 * ------------------------



        move.l  #prog_end,d6    ; Get address of end of this program

        sub.l   4(sp),d6        ; Subtract start of basepage - save in d6



        move.l  #not_auto,addrin ; Try to call form_alert

        move    #1,intin

        move.l  #f_alrt,aespb

        move.l  #aespb,d1

        move    #$C8,d0

        trap    #2

        tst     intout          ; If intout is zero, we're in \AUTO

        beq.s   .start1



        cmp     #1,intout       ; Did we click on "Install"?

        beq.s   .0              ; Yes, continue



        clr     -(sp)           ; Pterm0

        trap    #1              ; outta here



 .0:    pea     prg_start(pc)   ; Steal trap 2 right away if run from desktop

        move    #38,-(sp)       ; Supexec

        trap    #14

        addq    #6,sp



        move    #1,prgflg       ; Set flag indicating desktop load

        bra.s   .start2



 .start1:

        pea     title           ; Print title message

        move    #9,-(sp)

        trap    #1

        addq    #6,sp



 .start2:

        pea     set_bios(pc)    ; Appropriate the Trap 13 vector

        move    #38,-(sp)

        trap    #14

        addq.l  #6,sp



        clr.w   -(sp)           ; Terminate and Stay Resident

        move.l  d6,-(sp)        ; Number of bytes to keep

        move    #$31,-(sp)      ; That's all folks!

        trap    #1              ; We are now happily resident in RAM



 * -------------------------------

 *  Desktop vector initialization

 * -------------------------------



 prg_start:

        move.l  $88,t2_vec      ; Set my fall through addresses

        move.l  $88,aesvec

        move.l  #my_trap2,$88   ; Steal trap #2 (GEM)

        rts



 * -----------------------

 *  Steal the BIOS vector

 * -----------------------



 set_bios:

        move.l  $B4,t13adr      ; Set BIOS fall through address

        move.l  #my_t13,$B4     ; Steal trap #13 (BIOS)

        rts



 * ------------------------

 *  Trap #13 wedge routine

 * ------------------------



 my_t13:

        btst    #5,(sp)         ; Super or user mode?

        beq.s   t13_ex          ; If user mode, let's forget the whole thing

        cmp.l   #$050101,6(sp)  ; Setexec call for critical error vector?

        bne.s   t13_ex          ; Nope, let the call fall through



        tst     prgflg          ; Run from the desktop? Vectors set already?

        beq.s   first_time      ; No, skip ahead



 do_crit:

        move.l  #my_trap2,$88   ; Pilfer trap #2

        move.l  $404,d0         ; Get current critical error vector

        move.l  10(sp),d1       ; Get address we're setting it to

        bmi.s   t13_x1          ; If minus, return old vector in d0

        move.l  d1,$404         ; Set that vector

 t13_x1:

        rte                     ; Not a through street



 first_time:

        tst.l   10(sp)          ; Reading the vector?

        bmi.s   t13_ex          ; Yes, let the system take care of it

        cmp.l   #$FC0000,10(sp) ; Is this address below the ROMs?

        blo.s   t13_ex          ; Yes, bail out



        move    #1,prgflg       ; Set the 'first-time'/'desktop' flag

        move.l  2(sp),retsav    ; Save return address

        move.l  #t13_2,2(sp)    ; Replace it with my own

 t13_ex:

        jmp     $DEADBEEF       ; Go to the Bios



 t13adr  =       t13_ex+2



 t13_2:

        bsr     prg_start       ; Grab the trap #2 vector

        move.l  retsav,-(sp)    ; And return to the caller

        rts



 retsav:

        dc.l    0

 not_auto:

        dc.b    '[3][ Test alert box | ][ Install |Cancel]',0



---------------------------------------------------------------------



  (Whew!  This is turning out to be a lengthy message!)
Anyway, one really important point to remember when you
steal _any_ of the ST's trap vectors -- once you steal it,
NEVER reset it to what it was when you grabbed it.

 To disable yourself, use a flag and jump past your code, or some other
method...if you actually replace the vector itself, you'll be cutting
out any other programs that have installed themselves in the chain.

 Stealing an ST vector is like grabbing a tiger by the tail - once
you've got it, you'd better not let go!

(Note that the operating system itself is guilty of this crime.BIG sigh.)

  Now on to the "magic cookie" method Dan proposed...in a word, DON'T!

We just went through a real headache trying to make MultiDesk compatible
with Atari's Diablo emulator for their laser printer.
 The reason?  The Diablo program used a "magic cookie."
The Diablo emulator comes in two parts, a program that runs in the
AUTO folder and an accessory that is used to set up the emulator.

The accessory looks for a certain magic number right before thetrap #13
vector, in order to tell whether the AUTO program is installed or not.
  Works fine, again, as long as no one else steals the trap #13 vector
between the accessory and the AUTO program.  The trouble is, a LOT of programs
and accessories (including MultiDesk) steal trap #13.
  Result?  A big mess.

  A better method than the magic hockey puck is to issue an OS call with an
undefined function number, like BIOS #73, or AES #1200, and have your program
return a pre-defined value somehow, indicating that it's installed.
  For example, this is the method that G+PLUS uses to let other programs
know that it's installed.
  The program does a trap #2 call with $472B in register D1. 

If G+PLUS is present, it returns from the call after setting D1 to the address
of its "backdoor" structure....so if D1 is unchanged after the trap, G+PLUS
isn't there.

  Well, that's enough technical talk for one message.
  Feel free to ask if you have any questions about the source code I
included above.

- Charles

 ------------

Well I do hope that line noise did not corrupt this data, have only a
dumb upload option..
















































































































-- 
Roger W. Sheppard   85 Donovan Rd, Kapiti New Zealand...

hvaalde@cs.vu.nl (Aalderen van Harold) (05/26/91)

micro@imada.ou.dk (Klaus Pedersen) writes:

>When I tried to make the code that installed the Trap#2 handler I found
>that it was possible to use the vdi from the auto-folder, a thing that
>I thought was impossible! The trick is to open a physical screen work-
>station. Simple and clean...

I thought it was common knowledge already, but it seems it isn't
I use the following way to set up vdi from the autofolder in a way that 
the program can be run from the desktop to (use the program for over a year
no and the methode works on ST/STE and TT)

	appl_init();
	if (_GemParmBLk.global[0] == 0)	/* that is check AES version number */
		/* I am an auto prog */
		v_opnwk( etc )
	else
		/* AES already initialized */
		v_opnvwk( etc );

	writing this without the source code beside me and with TurboC in
	mind but it should look something like this.

The trick is that appl_init will not run if started from the auto folder
and thus the version number of AES will not be filled assuming initialized
global array this ends up as zero. So non-zero version number means AES 
available thus workstation opened thus I should open virtual one, zero means
no AES so it is save to open real workstation.
Ofcourse under no circumstances the program may end without closing the
workstation since it is not done automaticly, since there can be only one
real workstation AES will bomb if the auto program doesn't close his properly.

If anyone is interested in some more VDI tricks give me a mail.

Harold van Aalderen (hvaalde@cs.vu.nl)

ki@opal.cs.tu-berlin.de (Karsten Isakovic) (05/27/91)

In article <1991May24.184249.21414@imada.ou.dk> micro@imada.ou.dk (Klaus Pedersen) writes:
>Hi, 
>that it was possible to use the vdi from the auto-folder, a thing that
>I thought was impossible! The trick is to open a physical screen work-
>station. Simple and clean...
>
This trick is 'not new', it is used by some boot selector programms (X_BOOT
and in some PD boot selectors...), you find example programs in the manual
of NVDI or even in some (german) ST magazines.

Sincerly, Karsten

ki@opal.cs.tu-berlin.de (Karsten Isakovic) (05/27/91)

In article <1991May25.152208.2925@actrix.gen.nz> Roger.Sheppard@actrix.gen.nz
(Roger Sheppard) writes:
>This came from a File that I found some time back on Genie, it could
>be of help to otheres, with the Trap #2 problems.
>
>        btst    #5,(sp)         ; Super or user mode?
>        beq.s   t13_ex          ; If user mode, let's forget the whole thing
>        cmp.l   #$050101,6(sp)  ; Setexec call for critical error vector?

The code does not use the XBRA method, which _is_ standard...

> first_time:
>        tst.l   10(sp)          ; Reading the vector?
>        bmi.s   t13_ex          ; Yes, let the system take care of it
>        cmp.l   #$FC0000,10(sp) ; Is this address below the ROMs?
>        blo.s   t13_ex          ; Yes, bail out

And it does not work with RAM-TOS versions, or even with the new STE or
TT machines...  (Please use the os_start entry in the _sysbase structure
pointed to by the system variable $4f2.)

>  A better method than the magic hockey puck is to issue an OS call with an
>undefined function number, like BIOS #73, or AES #1200, and have your program
>return a pre-defined value somehow, indicating that it's installed.

This method is not good. The 'unused' function call might be used in a 
future TOS version.
You simply have to install a Cookie interface for the TSR. The value of
the cookie points to an internal TSR structure, so that a DA, CPX or PRG
can configure the TSR.

Sincerly, Karsten   (ki@opal.cs.tu-berlin.de)

micro@imada.ou.dk (Klaus Pedersen) (05/27/91)

Hi, 
Roger send this code, but please don't use it, because:
   o assumes that the ROM starts at $FC0000 (WRONG - might be $E00000 or
     something else.)
   o Don't use the XBRA protocol...
   o Don't use the longframe system var...

Also it say that the Trap2 vector gets taken all the time, I have not 
experinced that (but I am using tos1.4).
The code in the followup to Claus Brod question don't have these problems, 
please try to put the program from the post in the auto-folder, and let me 
know of problems.
And if you use the XBRA protocol you can unlink youself from any vector
chain (if all programs follow the protocol - and most do).
If you use the XBRA protocol you can see if you have been installed.
Please this is no flame, but a WARNING, don't use this code.

Roger.Sheppard@actrix.gen.nz (Roger Sheppard) writes:

>uniquely difficult because the operating system keeps replacing its own
>address in the vector!  TOS seems to reset $88 (trap #2) every time
>you runa .TOS or .TTP program, or show a file from the desktop.
> (And maybe at other times too...)

I have never seen that problem, ones you have it installed, it stays there
just as Allan have tried to say here!!! (Overscan runs - don't it?)
The only problem is when to take the trap2 vector from the AUTO folder.

...
> *  Trap #13 wedge routine

WHAT NO XBRA HEADER, PLEASE REMEMBER!!!

> my_t13:
>        btst    #5,(sp)         ; Super or user mode?
>        beq.s   t13_ex          ; If user mode, let's forget the whole thing
>        cmp.l   #$050101,6(sp)  ; Setexec call for critical error vector?

Say that it is not obvious, it is the same thing my program checks for!!
That is real funny.
This subroutine Don't use XBRA, Don't check  'longframe' don't run in user
mode... Please ()

...
> first_time:
>        tst.l   10(sp)          ; Reading the vector?
>        bmi.s   t13_ex          ; Yes, let the system take care of it
>        cmp.l   #$FC0000,10(sp) ; Is this address below the ROMs?

AUCH, WHAT IS THIS ^^^^^^, DON'T USE ANY THING LIKE THIS...  
THERE IS NO NEW ATARI COMPUTERS THAT RUNS THIS !!!! 



>Anyway, one really important point to remember when you
>steal _any_ of the ST's trap vectors -- once you steal it,
>NEVER reset it to what it was when you grabbed it.
> To disable yourself, use a flag and jump past your code, or some other
>method...if you actually replace the vector itself, you'll be cutting
>out any other programs that have installed themselves in the chain.

This is not true, If you use the XBRA protocol you can unlink yourself (or
any other :-) at any time!!!!


Sorry for disturbing you,

Klaus, micro@imada.ou.dk

stephen@oahu.cs.ucla.edu (Steve Whitney) (05/27/91)

Karsten, I'm not attacking you.  You're quite correct in the things you say,
but in defense of Mr. Johnson, I'm the "Steve" he was replying to on GEnie,
and that was _years_ ago.  Since then, he has written the "11 Commandments
of Trap Stealing" (or something like that) which addresses your concerns.

In article <3491@quepasa.cs.tu-berlin.de> ki@opal.cs.tu-berlin.de (Karsten Isakovic) writes:
>
>In article <1991May25.152208.2925@actrix.gen.nz> Roger.Sheppard@actrix.gen.nz
>(Roger Sheppard) writes:
>>This came from a File that I found some time back on Genie, it could
>>be of help to otheres, with the Trap #2 problems.
...
>The code does not use the XBRA method, which _is_ standard...

XBRA didn't exist yet when this snippet was captured.

>And it does not work with RAM-TOS versions, or even with the new STE or
>TT machines...  (Please use the os_start entry in the _sysbase structure
>pointed to by the system variable $4f2.)

Quite correct.

>This method is not good. The 'unused' function call might be used in a 
>future TOS version.
>You simply have to install a Cookie interface for the TSR. The value of
>the cookie points to an internal TSR structure, so that a DA, CPX or PRG
>can configure the TSR.

Again, the cookie jar didn't exist back then, and installing a cookie
isn't really that simple.  Unfortunately, any program that wished to install
a cookie must be prepared to creat a cookie jar if one does not yet exist.
This wouldn't be a problem in itself, but if it _does_ install a cookie jar,
it has to install a reset routine to clear the cookie jar location on a
reset.  Any program installing a cookie must also be prepared to install
a new jar if the current one is full.  In that case, the program must copy
all the cookies to the new jar, install its own cookie, and install a
routine at the reset vector.  Fun, huh?

By the way, I imagine that you know this, but some of our gentle readers
may not have played with cookies yet...

>Sincerly, Karsten   (ki@opal.cs.tu-berlin.de)

	--Steve


-- 
  Steve Whitney - UCLA CS Grad Student                       (())_-_(())
 Soon to be working at Silicon Graphics                       | (* *) | 
     Internet: stephen@cs.ucla.edu          UCLA Bruin-->    {  \_@_/  }
          GEnie:    S.WHITNEY                                  `-----'  

csbrod@immd4.informatik.uni-erlangen.de (Claus Brod) (05/27/91)

entropy@gnu.ai.mit.edu (maximum entropy) writes:

>Pardon me if I'm wrong, but everything I've ever read about the ST's
>GEM (specifically the Abacus volume) has said "V_OPNWK AND V_CLSWK ARE
>NOT IMPLEMENTED IN ATARI ST GEM" (OK, maybe they didn't use all caps
>:-) Isn't this a really bad idea, especially when you've just flamed
>someone for using undocumented variables in another posting?

Don't rely too much on the Abacus GEM book. It is legal to open a
physical workstation in a AUTO folder program.

----------------------------------------------------------------------
Claus Brod, Am Felsenkeller 2,			Things. Take. Time.
D-8772 Marktheidenfeld, Germany		 	(Piet Hein)
csbrod@medusa.informatik.uni-erlangen.de
Claus Brod@wue.maus.de
----------------------------------------------------------------------

Roger.Sheppard@actrix.gen.nz (Roger Sheppard) (05/27/91)

In article <1991May27.104903.10283@cs.ucla.edu> stephen@oahu.cs.ucla.edu (Steve Whitney) writes:
> Karsten, I'm not attacking you.  You're quite correct in the things you say,
> but in defense of Mr. Johnson, I'm the "Steve" he was replying to on GEnie,
> and that was _years_ ago.  Since then, he has written the "11 Commandments
> of Trap Stealing" (or something like that) which addresses your concerns.
> 
> >(Roger Sheppard) writes:
> >>This came from a File that I found some time back on Genie, it could
> >>be of help to otheres, with the Trap #2 problems.
> 
> >Sincerly, Karsten   (ki@opal.cs.tu-berlin.de)
> 
> 	--Steve
> -- 
>   Steve Whitney - UCLA CS Grad Student                       (())_-_(())
>  Soon to be working at Silicon Graphics                       | (* *) | 
>      Internet: stephen@cs.ucla.edu          UCLA Bruin-->    {  \_@_/  }
>           GEnie:    S.WHITNEY                                  `-----'  

Well I was not trying to start a war, but the Dates of that file where
in the Header part of it, I thought this would have been commonsense to
most people, that it could be a bit dated.

But maybe some one can post the 11 Commandments to the net.


-- 
Roger W. Sheppard   85 Donovan Rd, Kapiti New Zealand...

Roger.Sheppard@actrix.gen.nz (Roger Sheppard) (05/28/91)

In article <1991May27.001208.27105@imada.ou.dk> micro@imada.ou.dk (Klaus Pedersen) writes:
> Hi, 
> Roger send this code, but please don't use it, because:
  ^^^^^ I only posted this information.
Please read the Header that was in the Posting Please !.

> 
> Roger.Sheppard@actrix.gen.nz (Roger Sheppard) writes:
  ^^^^^^^^^^^^^^^^^^^^^                         ^^^^^^
Please read again, I did NOT write the article, Please read the
Header, I only posted it. !
> 
> Sorry for disturbing you,
> 
> Klaus, micro@imada.ou.dk

Please Klaus go back and read what was posted.
-- 
Roger W. Sheppard   85 Donovan Rd, Kapiti New Zealand...

ONM07@DMSWWU1A.BITNET (Julian F. Reschke) (05/28/91)

In article <1991May25.152208.2925@actrix.gen.nz>, Roger.Sheppard@actrix.gen.nz
(Roger Sheppard) says:
[stuff deleted]
>  A better method than the magic hockey puck is to issue an OS call with an
>undefined function number, like BIOS #73, or AES #1200, and have your program
>return a pre-defined value somehow, indicating that it's installed.
>  For example, this is the method that G+PLUS uses to let other programs
>know that it's installed.
>  The program does a trap #2 call with $472B in register D1.

Don't do things like that. This is the reason for the introfuction of the
cookie jar.
___________________________ cut here _____________________________________
Julian F. Reschke, Hensenstr. 142, D-4400 Muenster, Phone: ++49 251 861241
fast eMail: ONM07@DMSWWU1A.BITNET,    slow: jr@ms.maus.de (++49 251 77216)
____________________ correct me if I'm wrong _____________________________

ONM07@DMSWWU1A.BITNET (Julian F. Reschke) (05/28/91)

In article <ENTROPY.91May25060914@pogo.gnu.ai.mit.edu>, entropy@gnu.ai.mit.edu
(maximum entropy) says:
>
>Pardon me if I'm wrong, but everything I've ever read about the ST's
>GEM (specifically the Abacus volume) has said "V_OPNWK AND V_CLSWK ARE
>NOT IMPLEMENTED IN ATARI ST GEM" (OK, maybe they didn't use all caps
>:-) Isn't this a really bad idea, especially when you've just flamed
>someone for using undocumented variables in another posting?
>
This simply is not true. v_opnwk and v_clswk work absolutely ok, as
long as you only access the screen workstation. For printers and
other devices, you need GDOS - as documented in the official
docs and all good books.

>Or does GEM use these these functions itself upon starting up?
>
Sure. How could iot work otherwise?
___________________________ cut here _____________________________________
Julian F. Reschke, Hensenstr. 142, D-4400 Muenster, Phone: ++49 251 861241
fast eMail: ONM07@DMSWWU1A.BITNET,    slow: jr@ms.maus.de (++49 251 77216)
____________________ correct me if I'm wrong _____________________________