Thread: keyboard handlers & terminate and stay resident (tsr)

  1. #16
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    The first snippet of code was designed to be run to install the handler or designed to be a stub exe to be executed prior to the program using the handler. In other words the parent EXE would execute the stub first to install the handler. The problem I ran into was that because it was not an actual TSR there wasn't any good way to uninstall the handler. But what I did is when the exe is executed it queries the keyboard interrupt and checks the return code. If my handler is already installed it will return a value indicating it is already there. But if the old handler is there it won't know how to deal with the interrupt and will not return the correct value. This is how a lot of programs in the old DOS days checked to see if they were installed.

    If you want to make this a true TSR then you can do so, just make sure you limit the actual TSR portion to the relevant code only. For information on how to correctly use TSRs in DOS consult Randall Hyde's Art of Assembly Language Programming or the DOS 6.20-6.22 technical reference manual.

  2. #17
    Registered User
    Join Date
    Dec 2004
    Posts
    9
    there u are. now i have some idea. I think this way also works. why
    dont I just check the flags and scan codes at the same time like u
    suggest...

    Code:
    char far *kb = MK_FP(0,0x417);
    :
    :
    /* keyboard isr */
    void interrupt newhandler() {
       // okay.. check ctrl flag and 'd' character pls....
       if( (((*kb)&0x04)==0x04) && (inportb(0x60) == 0x20) ) {
          gotcha! there you are ctrl+d :-)
       else {
          I dunno what to do here, but I think need to restore oldhandler
          (*oldhandler)();
       }
        then send EOI
    }
    /* end interrupt */
    what do you think Bubba, need some changes? btw, if I press other
    key, that one will be printed on the console after the main program
    quits.. dont figure out yet y this happens...

  3. #18
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Well it looks like you are calling the old handler if CTRL D was not pressed. This is ok I guess if you want to simply trap for CTRL D and then pass everything else to the default handler.

    EOI is sent like this:

    outp(0x20,0x20);

    You will need to set a flag in your data segment from the handler that notifies your code that CTRL D has been pressed. You absolutely cannot do certain things inside of an interrupt handler because DOS is not re-entrant. Calling any DOS functions while the INDOS flag is set while you are inside of a handler will cause the system to crash hard. Best way is don't call any DOS functions inside of an interrupt handler that way you don't have to worry about re-entrancy issues. Also when you are installing your handler don't forget to turn off interrupts (CLI) and then when you are done installing it turn them back on (STI). This ensures that an interrupt will not be fired off amidst the code that installs the handler. You can also do this inside of the handler to ensure that while you are processing the keyboard input no interrupts will be fired off thus causing lots of problems.

    One problem with your code is that you are retrieving a key from the keyboard buffer but you are not telling the BIOS that you have retrieved the key. After so many keypresses every key after that will cause a nasty beep from the speaker. You must retrieve the value from the buffer, not just read it.

  4. #19
    Registered User
    Join Date
    Dec 2004
    Posts
    9
    Calling any DOS functions while the INDOS flag is set while you are inside of a handler
    will cause the system to crash hard.
    Already experienced this before :-). Up to this moment, I had to power
    my board on & off quite some time.. even ctrl+alt+del do not respond...

    Thanks Bubba, really appreciate your help. I dont think that any other
    keystrokes is important.. because at the end of my program I will issue
    a restart command, so my system will reboot. I just hope that I will be able
    to complete this project as soon as possible.... ;-)


    rgds,
    Triple_X

  5. #20
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Well to issue a reboot command in DOS this will work.

    Code:
    void Reboot(void)
    {
       asm { jmp FFFF:0000 }
    }
    But its been some time since I've coded this so I'm not sure it still works.
    Here is a webpage that will help more:
    http://www.geocities.com/SiliconVall...rebootcon.html

Popular pages Recent additions subscribe to a feed