[comp.sys.ibm.pc.programmer] TSR's with no assembly language

ho@fergvax.unl.edu (Tiny Bubbles...) (03/20/90)

From article <9771@wpi.wpi.edu>, by jhallen@wpi.wpi.edu (Joseph H Allen):
> In article <924@ns-mx.uiowa.edu> troj@icon.weeg.uiowa.edu () writes:
>>In <10125@portia.Stanford.EDU>,  dma@nova.stanford.edu (Domingo Mihovilovic A)
>>writes:

Frankly, I'm getting sick of all the Turbo/MSC/etc. fighting.  Stick it in
alt.flame or something.  It's all been heard before, several times...

But I *am* intrigued by assertions that you can write TSR's with no
assembly, by both languages.

It would seem, to my untrained mind, that using any high-level language to
write a TSR would eat up amazing amounts of memory to hold the run-time
library.  Even the most basic TSR requires a certain amount of run-time
kernel, on the order of a few K... doesn't it?

Also, how do you find out where your TSR "ends" (so you can feed the right
paragraph back to DOS in the TSR call)?
---
        ... Michael Ho, University of Nebraska
Internet: ho@hoss.unl.edu               USnail:  115 Nebraska Union
                                                 Lincoln, NE 68588-0461

jhallen@wpi.wpi.edu (Joseph H Allen) (03/20/90)

In article <2610@unocss.unomaha.edu> ho@hoss.unl.edu writes:
>From article <9771@wpi.wpi.edu>, by jhallen@wpi.wpi.edu (Joseph H Allen):
>> In article <924@ns-mx.uiowa.edu> troj@icon.weeg.uiowa.edu () writes:
>>>In <10125@portia.Stanford.EDU>,  dma@nova.stanford.edu (Domingo Mihovilovic A)
>>>writes:

>But I *am* intrigued by assertions that you can write TSR's with no
>assembly, by both languages.

>It would seem, to my untrained mind, that using any high-level language to
>write a TSR would eat up amazing amounts of memory to hold the run-time
>library.  Even the most basic TSR requires a certain amount of run-time
>kernel, on the order of a few K... doesn't it?

>Also, how do you find out where your TSR "ends" (so you can feed the right
>paragraph back to DOS in the TSR call)?

Use tiny model and peak into the paragraph prior to the PSP.  You can subtract
out _stklen and part of _heaplen to make it even smaller.

Turbo C requires a minimum of 1742 bytes to run.  Included will be the memory
allocator and command line parameter routines.  Whatever you do, don't use
printf.  It adds 6K.  If you're a real minimist you can make it less by
replacing c0t.obj with this:  

_TEXT   SEGMENT BYTE PUBLIC 'CODE'
_TEXT   ENDS
_DATA   SEGMENT WORD PUBLIC 'DATA'
_DATA   ENDS
_BSS    SEGMENT WORD PUBLIC 'BSS'
_BSS    ENDS
_LAST   SEGMENT WORD PUBLIC 'LAST'
_LAST   ENDS
DGROUP  GROUP _TEXT, _DATA, _BSS, _LAST

_TEXT   SEGMENT BYTE PUBLIC 'CODE'
        ASSUME  CS:_TEXT,DS:DGROUP,ES:DGROUP,SS:DGROUP
        org     0100h
start:
        extrn   _main:near
        jmp     _main
_TEXT   ENDS
_LAST   SEGMENT WORD PUBLIC 'LAST'
        public  _top
_top    equ     $
_LAST   ENDS
        end     start

The size of the program is the address of '_top'.  But of course, this is
cheating...  but then 1 assembly language instruction isn't all that bad.
Also most of the turbo C library won't work, but the C support functions for
far pointers, structure copying and longs will.  These are the support
object modules if you want to really trim down cs.lib:

SCOPY LXMUL DIVT LDIV LDIVT LROTL LROTR LRSH LLSH LURSH SETJMP SPUSH ROTL ROTR

(I also include SETJMP as being part of the C language and not part of
library).

The one include file that you really nead is dos.h.  It prototypes the rest of
turbo C's features which are really language features, not library.

Best of all... the debugger still works in this very tiny model.

With a slightly different startup module you can even make device drivers
(you have to change the stack to get this to work so it isn't very pretty).
I'm curious about the Microsoft C equivelent of all this is.  I didn't even
know MSC had pseudoregisters- this is a new addition in MSC 6.0 is it not? 
-- 
            "Come on Duke, lets do those crimes" - Debbie
"Yeah... Yeah, lets go get sushi... and not pay" - Duke

mac@idacrd.UUCP (Robert McGwier) (03/21/90)

From article <2610@unocss.unomaha.edu>, by ho@fergvax.unl.edu (Tiny Bubbles...):
> From article <9771@wpi.wpi.edu>, by jhallen@wpi.wpi.edu (Joseph H Allen):
>>>writes:
> 
> Frankly, I'm getting sick of all the Turbo/MSC/etc. fighting.  Stick it in
> alt.flame or something.  It's all been heard before, several times...
> 
> Also, how do you find out where your TSR "ends" (so you can feed the right
> paragraph back to DOS in the TSR call)?


_PSP is a variable recognized by MSC 5.1 and I <<ASSUME>> it is also
recognized by Turbo C.  You can then take the tiny assembler fragment
posted here earlier and essentially emulate it in C.  The only time
my TSR's are really big are when I load floating pointing emulation
routines in.  I have a complete satellite tracking system, written
as a TSR, computes on the timer tick, and aims the antennas at the
satellite.  This is 16K and is full of floating point.  DO NOT FORGET
THAT IF YOU USE THE COPROCESSOR in a TSR you must first preserve
the entire state of the coprocessor of the running process and then
reinstate the TSR's state.  The inverse of this must be done on exit.
If your code can blow up, you must also steal the divide by zero and
other floating point exceptions only during the time you are executing
unless you want to have your TSR's foul ups trapped by another running
program, etc.  I find writing TSR's in C to be extremely easy in MSC 5.1,
with just a few rules such as I have pointed out here.  I have even made
use of the DOS critical section flags, etc.

On MSC 5.1 and far malloc, I have written another package, which does malloc,
frees, reallocs, etc, 58000 byte blocks and I have NEVER ONCE seen it
fail in the large model.  The total code used is 320000 bytes and I
have yet to have a single problem with MSC 5.1. I have Turbo 2 but just
can't seem to find the time to learn its vagaries and move the any code
over in order to test whether or not it is truly better or worse.  I
did find a bug in strrchr which others on the USENET have made postings
about and have fixes to the Turbo C library for this function.  IMHO,
the support from all of the compilers for Large model programs still
leaves a bit to be desired.  I am anxiously awaiting my update card to
arrive for Microsoft C 6.0.

Bob
 
-- 
____________________________________________________________________________
    My opinions are my own no matter	|	Robert W. McGwier, N4HY
    who I work for! ;-)			|	CCR, AMSAT, etc.
----------------------------------------------------------------------------

nol2321@dsacg2.dsac.dla.mil (Jim Dunn) (03/21/90)

RIDICULOUS!!!

Trying to say which C compiler is best is like trying to suggest that a Ford
is better than a Chevy, or that a Blonde is better than a Red-head.

AGAIN RIDICULOUS!!!

When all is said and done, you have to admit that it's not what you have,
but HOW you use it.  This holds true for EVERYTHING!

You can spend all the money you want on whatever C compiler brags the most in
it's expensive ads (which YOU pay for in the end!), but if you can't program
it to do what you need... you're out of luck!

Well, there's my 2 cents worth...  don't bother flaming, I bought a CHEAP fire
suit, and WEAR IT WELL...

:)

 Jim Dunn c/o DSAC-OLC, P.O. Box 1605, Columbus, OH 43216-5002   (614) 238-9713
 Internet: jimdunn@dsacg2.dsac.dla.mil  [131.78.1.2]                AV 850-9713
 UUCP: ...!osu-cis!dsac!dsacg2!jimdunn  DLA Systems Automations Center, DSAC-OL
 God-Jesus-Holy_Spirit-Universe-Milky_Way-SOL_III-Earth-USA-DoD-DSAC-OLC-Me! :)

weeks@ssbell.IMD.Sterling.COM (John Weeks) (03/22/90)

In article <2610@unocss.unomaha.edu> ho@hoss.unl.edu writes:
>
>But I *am* intrigued by assertions that you can write TSR's with no
>assembly, by both languages.
>
>It would seem, to my untrained mind, that using any high-level language to
>write a TSR would eat up amazing amounts of memory to hold the run-time
>library.  Even the most basic TSR requires a certain amount of run-time
>kernel, on the order of a few K... doesn't it?

Yep, depending of course, on what functions get linked in.  You can write
a TSR that pops up and says "Hi, there!" that takes 20K.  On the other
hand, with carefull pruning, you can cram a fair amount of functionality
in a reasonable amount of space.  But I was looking at a shareware demo of
an hp28c calculator program recently.  The TSR required something in the range
of 150-200K!  Whats the point?  It strikes me that that is a misapplication
of TSR technology.  Are there really users who require this functionality
in a pop up mode (instead of forking a shell) and yet are running an
application that leaves room for this in memory?

                                  -jw-

-- 

John Weeks                                    Phone:  (402) 291-8300
Sterling Software FSG/IMD        e-mail: uunet!ssbell!weeks
1404 Ft. Crook Rd. South         e-mail: weeks@ssbell.IMD.Sterling.COM

nol2321@dsacg2.dsac.dla.mil (Jim Dunn) (03/27/90)

Well... c'mon "mac"!  Let's see some of that "TSR C SOURCE CODE"!!!  Otherwise
I'm not gonna be convinced!

:)

mac@idacrd.UUCP (Robert McGwier) (03/28/90)

From article <1981@dsacg2.dsac.dla.mil>, by nol2321@dsacg2.dsac.dla.mil (Jim Dunn):
> Well... c'mon "mac"!  Let's see some of that "TSR C SOURCE CODE"!!!  Otherwise
> I'm not gonna be convinced!
>



Sorry, I didn't realize people were waiting for me to post some.  I will
bundle up a small program that steals the timer interrupt, chains through
to the previous handler, and determines how much memory it needs to save.
I apologize to Turbo C users, I don't know how to accomplish the same
goal in Turbo C.  Coming soon to a mailbox near you!!



Bob
 
-- 
____________________________________________________________________________
    My opinions are my own no matter	|	Robert W. McGwier, N4HY
    who I work for! ;-)			|	CCR, AMSAT, etc.
----------------------------------------------------------------------------

morash@ug.cs.dal.ca (Dave Morash) (04/07/90)

I just recently picked up a copy of 'Born to Code in C' by Herbert Schildt
(ISBN 0-07-881468-5) which contains a chapter on a TSR written entirely in
Turbo C. He covers which interrupts you need to hook into and why etc. It 
seems to be a very good explanation of TSR's (in only 60 pages with source
for a complete TSR at that too!)


-- 
dalcs!dalcsug!morash@uunet.uu.net | dalcs!dalcsug!morash@watmath.waterloo.edu
morash%dalcsug@dalcs.uucp         | morash%dalcsug%dalcs@watmath.uucp
morash%dalcsug%dalcs@uunet.uucp   l morash@ug.cs.dal.ca

rbr@bonnie.ATT.COM (4197,ATTT) (04/08/90)

In article <8561@cg-atla.agfa.com> fredex@cg-atla.UUCP (Fred Smith) writes:
>There was an article in Microsoft System Journal a couple of years
>ago by Kaare Christian which described the process of writing a
>TSR entirely in Microsoft C, and gave a simple example TSR in
>source code. I typed the sucker in and voila! it worked just
>fine.  

How about posting the surce for the example TSR




Thanks in advance,

Bob Rager

seven@nuchat.UUCP (David Paulsen) (04/08/90)

And now, from the Believe It Or Don't file...

I recall an article in _PC Magazine_ a few months ago that reviews
something called POP BASIC, which is itself a TSR.  In other words,
a memory resident BASIC interpreter available at all times, triggered
by a hot key.  While not as robust an environment as the other BASICs
reviewed in that same issue, POP BASIC did have one interesting feature:
it could create stand-alone TSRs.  That's right, type in a weasely li'l
10-line program (I guess) and punch the magic button (or run it thru
the magic compiler, or mumble the magic words, or scrifice that
virgin you've been saving..) and out comes your program, but in
a ready-to-use TSR form.  At least that's what the reviewer thought.

Intriguing, to say the least.  Anyone even SEEN this package?  I think
the retail price was <$100.

David

-- 
David Paulsen    ..uunet!nuchat!seven  ||| The Curiosity Shop BBS, 713/326-3729
-------------------------------------------------------------------------------
Q: What do you get when you cross a dyslexic with an atheist?
A: Someone who doesn't believe in dogs.

muselikj@spock (Jiri Muselik) (04/09/90)

In article <21531@nuchat.UUCP> seven@nuchat.UUCP (David Paulsen) writes:
>And now, from the Believe It Or Don't file...
>
>I recall an article in _PC Magazine_ a few months ago that reviews
>something called POP BASIC, which is itself a TSR.  In other words,
>a memory resident BASIC interpreter available at all times, triggered
>by a hot key.  While not as robust an environment as the other BASICs
>reviewed in that same issue, POP BASIC did have one interesting feature:
>it could create stand-alone TSRs.  That's right, type in a weasely li'l
>10-line program (I guess) and punch the magic button (or run it thru
>the magic compiler, or mumble the magic words, or scrifice that
>virgin you've been saving..) and out comes your program, but in
>a ready-to-use TSR form.  At least that's what the reviewer thought.
   ^^^^^^^^^^^^^^^^^^^^^

There is nothing magic about adding an interrupt call for TSR anywhere.
I haven't done this (I am using Turbo Pascal for my TSR's) but
even TURBO BASIC offers access to interrupts and virtual registers, so if you
intend to use BASIC, you may consider this as well. It does not inject a
TSR call automatically but it is solid as BASIC could be [ :-)].

In any case - if you are going to play around with TSRs, it is more than
likely that any good handbook on interrupts will become a necessity regardless
if you are using assembler or high level language.

>
>Intriguing, to say the least.  Anyone even SEEN this package?  I think
                                            ^^^^
                                            Sorry, can't help here.
>the retail price was <$100.
                       ^^^^^
                       TB sells for something like $80 (possibly less).
>
>David
>

...Jiri
-- 
A friend of state-of-the-art,
an enemy of control sequences.

jrv@demon.siemens.com (James R Vallino) (04/09/90)

In article <127@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>In article <27810@siemens.siemens.com> jrv@demon.siemens.com (James R Vallino) writes:
>
>>There is at least one potentially fatal flaw in writting interrupt routines
>>"without a drop of assembly" using MSC or QuickC.  The last time I checked I
>>could not find anyway to switch to a local stack while executing the
>>interrupt.
>
>    MSC 5.0 and beyond have Memory model customization swicthes that
>lets you select a separate stack segment.  RTFM User's Guide, 6.5.3

If there is anyone who can show me the method to use a local stack when my
MSC "all C" interrupt is called I would be most appreciative.  As far as I
can determine the compiler flags which are desribed in User's Guide, 6.5.3,
do didly to allow you to control your stack within the interrupt routine.  (I
already had read the manuals and the README file where the interrupt
attribute is described.  Flame withheld.)  I still stand by my statement that
interrupts in MSC "without a drop of assembly" are potentially dangerous.

Jim Vallino	Siemens Corporate Research, Inc., Princeton, NJ
jrv@demon.siemens.com
princeton!siemens!demon!jrv
(609) 734-3331

dts@pwllheli.sw.stratus.com (Daniel Senie) (04/11/90)

|>If there is anyone who can show me the method to use a local stack when my
|>MSC "all C" interrupt is called I would be most appreciative.  As far as I
|>can determine the compiler flags which are desribed in User's Guide, 6.5.3,
|>do didly to allow you to control your stack within the interrupt routine.  (I
|>already had read the manuals and the README file where the interrupt
|>attribute is described.  Flame withheld.)  I still stand by my statement that
|>interrupts in MSC "without a drop of assembly" are potentially dangerous.

I have sucessfully done similar things in Turbo C. One key element. MAKE
SURE you disable
the compiler option for stack checking logic. If you don't the code the
compiler generates goes haywire on occasion and takes out the machine...
                       
Daniel Senie               UUCP: uunet!lectroid!dts 
Stratus Computer, Inc.     ARPA: dts@lectroid.sw.stratus.com
55 Fairbanks Blvd.         CSRV: 74176,1347
Marlboro, MA 01752         TEL.: 508 - 460 - 2686

jhallen@wpi.wpi.edu (Joseph H Allen) (04/12/90)

In article <28050@siemens.siemens.com> jrv@demon.siemens.com writes:
>If there is anyone who can show me the method to use a local stack when my
>MSC "all C" interrupt is called I would be most appreciative.

I don't know about MSC but in TC:

#include <dos.h>

unsigned osp;		/* Place to save old stack */
unsigned oss;

unsiged localstack[1024];

interrupt foo()		/* The interrupt call itself changes CS:PC,
			   the function handler changes DS */
{
osp=_SP;
oss=_SS;
disable();
_SS=_DS;
_SP=(unsigned)localstack+1024;
enable();
func();			/* Call to your code */
disable();
_SS=oss;
_SP=osp;
enable();
}

Notes:

This is for small & tiny model.  You'll need to do different things for larger
memory models:  You'll have to set SS to a different value.  

You absolutely MUST NOT define any local variables in the interrupt handler-
instead define them in the subfunction 'func()'.  This is because if you
define any local variables they will go on the old stack.

This does put 18 bytes on the old stack for saving the registers (access these
indirectly through osp and oss).  This should be much safer than not changing
the stack at all.

Instead of allocating space for a stack, a better way is to have the TSR
install code remember where the original stack was.

It is probably possible to remove the 'disable()' and 'enable()'s.  This is
because the 8088 keeps interrupts off for the next intruction after loading
SS.  But check that the SP load is only a single instruction first before
doing this (Note that in TC enable() and disable() are inline functions if you
include dos.h). 
-- 
             ~ COMPLETELY FUNCTIONAL SIGNATURE - NO FRIVOLITY HERE ~
REPLIES/FOLLOWUPS SHOULD BE SENT TO: jhallen@wpi.wpi.edu (130.215.24.1)
DISCLAIMER: I'm personally resposible for everything I say.  So, if you have
	    a problem feel free to sue me.

jhallen@wpi.wpi.edu (Joseph H Allen) (04/12/90)

In article <11433@wpi.wpi.edu> jhallen@wpi.wpi.edu (Joseph H Allen) writes:
>In article <28050@siemens.siemens.com> jrv@demon.siemens.com writes:
>>If there is anyone who can show me the method to use a local stack when my
>>MSC "all C" interrupt is called I would be most appreciative.

>I don't know about MSC but in TC:

>#include <dos.h>

>unsigned osp;		/* Place to save old stack */
>unsigned oss;

>unsiged localstack[1024];

>interrupt foo()		/* The interrupt call itself changes CS:PC,

>{
>osp=_SP;
>oss=_SS;
>disable();
>_SS=_DS;
>_SP=(unsigned)localstack+1024;
>enable();
>func();			/* Call to your code */
>disable();
>_SS=oss;
>_SP=osp;
>enable();
>}

>Notes:

>This is for small & tiny model.  You'll need to do different things for larger
>memory models:  You'll have to set SS to a different value.  

>You absolutely MUST NOT define any local variables in the interrupt handler-
>instead define them in the subfunction 'func()'.  This is because if you
>define any local variables they will go on the old stack.

>This does put 18 bytes on the old stack for saving the registers (access these
>indirectly through osp and oss).  This should be much safer than not changing
>the stack at all.

>Instead of allocating space for a stack, a better way is to have the TSR
>install code remember where the original stack was.

>It is probably possible to remove the 'disable()' and 'enable()'s.  This is
>because the 8088 keeps interrupts off for the next intruction after loading
>SS.  But check that the SP load is only a single instruction first before
>doing this (Note that in TC enable() and disable() are inline functions if you
>include dos.h). 

Oops, that's the non-reentrant version.  You can use it but you have to be
very carefull.  A better one is this:

#include <dos.h>
unsigned osp;		/* Place to save old stack */
unsigned oss;
unsiged localstack[1024];

interrupt foo()		/* The interrupt call itself changes CS:PC,
			   the function handler changes DS */
{
if(_SS==_DS) func();
else
 {
 osp=_SP;
 oss=_SS;
 disable();
 _SS=_DS;
 _SP=(unsigned)localstack+1024;
 enable();
 func();			/* Call to your code */
 disable();
 _SS=oss;
 _SP=osp;
 enable();
 }
}

Ok, so who's going to make a multi-tasking OS (in C only) now that we have
context switching code?



















Someday I'm going to write a new non-braindamaged news system.
-- 
             ~ COMPLETELY FUNCTIONAL SIGNATURE - NO FRIVOLITY HERE ~
REPLIES/FOLLOWUPS SHOULD BE SENT TO: jhallen@wpi.wpi.edu (130.215.24.1)
DISCLAIMER: I'm personally resposible for everything I say.  So, if you have
	    a problem feel free to sue me.