• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 326
  • Last Modified:

Invoking a TSR

Can anybody give me a sample TSR code just to print "Hello World" when ALT+SHIFT is pressed.
I am using MS C 7.00
0
ravipal
Asked:
ravipal
1 Solution
 
ravipalAuthor Commented:
Adjusted points to 30
0
 
JYoungmanCommented:
Screen output is very difficult in TSRs becasue DOS is not reentrant.   Neither is the BIOS or at least some parts of it.

0
 
shchukaCommented:
If you're working with DOS, you can easily output text into a text mode screen by writing character into the memory.  The idea is very simple.  The 1st char of the 1st line is the address 0xb800:0000 in color mode and 0xb000:0000 in monochrome mode.  The next byte following is the attribute (color, blink, underline, etc), the next byte is the char of in the second position on the line, etc...
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
vladimir_12345Commented:
This is a simple skeleton that works. But I have only
Borland 4.5 Compiler for DOS programs. If you will have problems
with this source I will help you.
TSR area is very difficult and from this source to "true" TSR
it is a very long road.
================================================================

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>

typedef void interrupt (*INTERRUPT)(void);

void interrupt Int9(void);
void RemoveTSR(void);
void PrintScreen(void);

INTERRUPT OldInt9;

extern unsigned _heaplen = 1024;
extern unsigned _stklen  = 1024;

int main()
{
      unsigned TSR_Size = _SS + (_SP+15)/16 - _psp;

      OldInt9 = getvect(9);
      setvect(9, Int9);

      keep(0, TSR_Size);
      return 0;
}

void interrupt Int9(void)
{
      static char* pKbdStatus = (char*)0x00400017L;

      OldInt9();

      // if Ctrl is pressed - remove TSR from memory
      if(*pKbdStatus & 4)
            RemoveTSR();

      // if Shift+Alt are pressed print ...
      if((*pKbdStatus & 3) && (*pKbdStatus & 8))
            PrintScreen();
}

void RemoveTSR(void)
{
      setvect(9, OldInt9);

      freemem(_psp);
      freemem(*(unsigned _far*)MK_FP(_psp, 0x2C));
}

void PrintScreen(void)
{
      printf("Hello World !!!\n");
}

0
 
xyuCommented:
This is a vey dangerous example... depend to implementation of the Run-Time Library.... printf may use function 21 of DOS... and this will cause problems with nonreenterability of DOS functions...I solved it many years ago using "busy" flag and keyboard iddle function originally implemented by MS for background PRINTing :) (i used Turbo Pascal 5.5 that time)
I'll send the source of it tommorow :)
0
 
jeseemCommented:
If it is necesary to call printf in a 21interrupt the dos critical data should be saved.
However in a TSR it is preferable to directly write to screen as shchuka has said.
0
 
arun_taCommented:
Do not call a printf() in any TSR because almost all implementations of printf() uses DOS fn 48 to malloc and DOS is not reentrant. You must directly write to video memory at B800:0000.
Also the code to remove the TSR will cause problems. The best methode is to find the start of MCB (Memory Control Block) chain and follow it to find the memory blocks owned by the TSR and release them one by one (Highly Complex!).
 
0
 
xyuCommented:
Hi...
Here is example of the legitimate TSR...
Sorry but I don't have any time to translate it to C...
and I don't have any sutable compiler to debug it now...
but it's very easy to translate

Note:
  The IntKbd procedure doesn't perform real operations...
it's just triggering an flag that should be processed in appropriate time.
  The IntTime and IntKvantDos procedures are responsible for the processing
initiation.
  The IntTime checks the "DOS Busy" flag, and the IntKvatDos checks the
state when DOS waits for input...
  It is undefined what procedure is going to be executed first...
so you have to implement both of them

      Good Luck...
P.S. Change to something better than DOS :) (UNIX or NT or Win95 at least)
      

{$A+,B-,D-,E-,F-,I-,L-,N-,O-,R-,S-,V-}
{$M 1024,0,0}
Uses
  Dos;

Const
  FileName : string = 'DIALOG.DAT';
  Message  : string = 'Yes';

Var
  KbdIntVec      : procedure;
  IntKvantDosVec : procedure;
  IntTimeVec     : procedure;
  f              : Text;
  Flag           : boolean;
  DosWork        : ^byte;
  Reg            : registers;

{$F+}

Procedure FileWrite;

begin
  Rewrite(f);
  Write(f,Message);
  Close(f);
  Flag:=false
end;

Procedure IntTime; interrupt;

begin
  inline($FA);
  if Flag and (DosWork^=0) then FileWrite;
  inline($FB);
  inline($9C);
  IntTimeVec
end;

Procedure IntKvantDos; interrupt;

begin
  inline($FA);
  if Flag then FileWrite;
  inline($FB);
  inline($9C);
  IntKvantDosVec
end;

Procedure IntKbd; interrupt;

begin
  Flag:=(Port[$60]=$44);
  inline($9C);
  KbdIntVec
end;

{$F-}
begin
  Assign(f,FileName);

  inline($FA); { CLI }

  Reg.Ah:=$34; { Set DosWork to Flag of Dos activity }
  Intr($21,Reg);
  DosWork:=Ptr(Reg.Es,Reg.Bx);

  GetIntVec($28,@IntKvantDosVec);
  SetIntVec($28,@IntKvantDos);

  GetIntVec($8,@IntTimeVec);
  SetIntVec($8,@IntTime);

  GetIntVec($9,@KbdIntVec);
  SetIntVec($9,@IntKbd);

  inline($FB);

  Keep(0)
end.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now