delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2006/02/04/09:31:42

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
From: "Rod Pemberton" <dont_have AT bitbucket DOT cmm>
Newsgroups: comp.os.msdos.djgpp
References: <43E12016 DOT 2070308 AT mainstreetsoftworks DOT com> <7t88b3-d2q DOT ln1 AT news DOT infowest DOT com> <43E1863D DOT 8080308 AT mainstreetsoftworks DOT com> <fgt8b3-c4u DOT ln1 AT news DOT infowest DOT com> <43E216B4 DOT 70509 AT mainstreetsoftworks DOT com> <43E243F8 DOT 7060401 AT mainstreetsoftworks DOT com> <1o8ab3-2i71 DOT ln1 AT news DOT infowest DOT com> <k2qab3-d7b1 DOT ln1 AT news DOT infowest DOT com> <43E2C6DA DOT 4080700 AT mainstreetsoftworks DOT com> <4mcbb3-q1f1 DOT ln1 AT news DOT infowest DOT com> <43E3884C DOT 8050308 AT mainstreetsoftworks DOT com>
Subject: Re: TSR issues (with code)
Lines: 339
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1437
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1441
X-IWN-Posted-By: [68.60.59.250] Sat Feb 4 03:02:40 2006
Message-ID: <0naeb3-s442.ln1@news.infowest.com>
X-Complaints-To: abuse AT eli DOT net
X-Trace: 52616e646f6d49564b835516cab6b1f728cd0aaad111e06a2859ca5fe614c2a3fdb4d17c804a296421caf04f2ab9f82170ebc33cd18900c8cba20211efcef77aa16fdcb2896aeb57ee6c834218679391d610aa01f4b5927abbe878f1445c3c72b530b814c3ca00069a9c9537f2d821afab488be512f9e4854af0256693d7ad2b8dd4fd381c7c89be3aec074545667f09
X-Abuse-Info: Please be sure to forward ALL headers so that we may process your complaint properly.
NNTP-Posting-Date: Sat, 04 Feb 2006 10:19:58 UTC
Date: Sat, 04 Feb 2006 14:17:34 GMT
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

"Brad House" <brad AT mainstreetsoftworks DOT com> wrote in message
news:43E3884C DOT 8050308 AT mainstreetsoftworks DOT com...
> Ok, doing realmode reflection doesn't look like it's too bad then...
> And you suggest using _go32 function instead of __dpmi functions,
> so to chain the interrupt vector, how would that work, it seems as
> though there is no _chain_ routine, would I simply call the old
> dos realmode int's  pm_offset assuming the _go32_dpmi wrappers
> made such a routine for me?  This is how I think it _should_
> look:

I've got it working.  I'll inline all three after my signature.

1) DIR/S lockup is due to write() calling a dos interrupt
2) for INDOS it's, r.x.es. You used ds.
3) my preference, I changed r.x.es*16+r.x.bx to (r.x.es<<4)|r.x.bx
4) replaced write with custom routine owrite()

Rod Pemberont

----
#ifndef __TSR_H__
#define __TSR_H__
typedef void (*mycallback)(void);
int create_tsr(mycallback hook);
int remove_tsr();
void owrite(char *);
//#define DEBUG
#endif
----
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/nearptr.h>
#include "tsr.h"

static int cnt=0,x=0,y=0;

void owrite (char *p)
{
    char line[80];
    char *screen = (char *)0xB8000;
    int i;

    screen-=__djgpp_base_address;
    memset(line,0,sizeof(line));
    sprintf(line,"%s",p);
    for (i=0;i<strlen(line);i++)
    {
       if(line[i]!='\n')
       {
           screen[x*80*2+2*y]=line[i];
           screen[x*80*2+2*y+1]=0x6F;
           y++;
       }
       if(y==80||line[i]=='\n')
       {
         y=0;
         x++;
         if(x==25)
             x=0;
       }
    }
};

void tsr_callback(void)
{

#ifdef DEBUG
    owrite("tsr_call");
#endif
    cnt++;
    if ((cnt % 100) == 0)
    {
        owrite("100 more\n");
    }
    if (cnt == 10000)
    {
        owrite("removing tsr...\n");
        remove_tsr();
        owrite("removed!\n");
    }
}

int main(void)
{
    __djgpp_nearptr_enable();

    owrite("Creating tsr...\n");
    if (!create_tsr(tsr_callback))
    {
        owrite("failed\n");
        return(1);
    }

/* Should never actually get here, because */
/* we terminated and stayed resident */
return(0);
}
----

/* DJGPPTSR, Nov 1995 Charles Sandmann (sandmann AT clio DOT rice DOT edu)
   Updated Oct 2002.

   ABSOLULTELY NO WARRANTY.  May be redistributed or copied without
restriction.

   An example of a DJGPP TSR.  This routine changes the video attribute of
the
   character in the upper right of the screen once per tick (from protected
   mode).  The DPMI provider will be forced to stay resident after this
image
   exits.  This code also shows an undocumented way to suppress the
exception
   code loading to decrease the image footprint size.  Not optimal - you can
   do the same thing with a single GAS file with a much smaller image.  Left
   as an exercise for the user.  Have fun!


   Trying to modify to allow DOS calls from within TSR...
- Brad House 2006
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <go32.h>
#include <dpmi.h>
#include <crt0.h>
#include <dos.h>
#include <pc.h>
#include <unistd.h>
#include <sys/exceptn.h>
#include <sys/farptr.h>
#include "tsr.h"

#define asm_cli disable
#define asm_sti enable

#define TIMER_INTERRUPT 0x1c
#define IDLEDOS_INTERRUPT 0x28 /* DOS idle interrupt */

/* FLAG to lock all memory */
int _crt0_startup_flags = _CRT0_FLAG_LOCK_MEMORY|_CRT0_FLAG_UNIX_SBRK;

volatile int indos_offset;    /* saved INDOS flag address */
volatile int critical_offset; /* saved critical error flag */
volatile int in_int28=0; /* check to see if we're in an int28 call */
volatile int in_callback=0; /* check to see if it's trying to reenter */
mycallback int_callback=NULL;

/* Place to store old interrupt vectors */
_go32_dpmi_seginfo old_int8_vector;
_go32_dpmi_seginfo old_int28_vector;
_go32_dpmi_registers r;

/* Calls int 21 ax 0x3100 to tell app to terminate and stay resident */
void keep(unsigned char status, unsigned size)
{
#ifdef DEBUG
    owrite("keep ");
#endif

/* Keep size default is current PSP block size */
    if(_farpeekw(_dos_ds,_go32_info_block.linear_address_of_original_psp-15)
        !=(_go32_info_block.linear_address_of_original_psp/16))
/* Not a real PSP? attempt to continue */
        r.x.dx=(_go32_info_block.size_of_transfer_buffer+256)/16;
    else

r.x.dx=_farpeekw(_dos_ds,_go32_info_block.linear_address_of_original_psp-13)
;

/* Default is to keep PSP and transfer buffer, but the user may want to */
/*   not use and release transfer buffer to decrease DOS footprint.  */
    if(size>=16&&size<r.x.dx)
        r.x.dx=size;
    r.x.ax=0x3100+status;
    __dpmi_int(0x21, &r);
}

unsigned char _peekb(int dosoffset)
{
    unsigned char c;

#ifdef DEBUG
    owrite("_peekb ");
#endif
    dosmemget(dosoffset, sizeof(c), &c);
    return(c);
}


int tsr_execute_allowed()
{
    char indos, critical;

#ifdef DEBUG
    owrite("tsr_exec ");
#endif

    indos=_peekb(indos_offset);
    critical=_peekb(critical_offset);

    if(indos==0&&critical==0)
        return(1);

/* If we're only in an int28 call, it's ok */
    if (indos == 0x01 && critical == 0 && in_int28 == 1)
        return(1);

return(0);
}

void myint28_function(void)
{
#ifdef DEBUG
    owrite("\nmyint28 ");
#endif
    asm_cli();   /* Block interrupts */

/* Increment int28 cntr so we know we're being */
/* called from the int28 callback */
    in_int28++;
    if(tsr_execute_allowed()&&!in_callback)
    {
        in_callback++;
        (*int_callback)();
        in_callback--;
    }

/* Decrement counter as we exit */
    in_int28--;
    asm_sti(); /* Unblock interrupts */

/* Chain interrupt */
    r.x.cs = old_int28_vector.rm_segment;
    r.x.ip = old_int28_vector.rm_offset;
    _go32_dpmi_simulate_fcall_iret(&r);
}

void myint8_function(void)
{
#ifdef DEBUG
    owrite("\nmyint8 ");
#endif
    asm_cli(); /* Block interrupts */
    if(tsr_execute_allowed()&&!in_callback)
    {
        in_callback++;
        (*int_callback)();
        in_callback--;
    }
    asm_sti(); /* Unblock interrupts */

/* Chain interrupt */
    r.x.cs = old_int8_vector.rm_segment;
    r.x.ip = old_int8_vector.rm_offset;
    _go32_dpmi_simulate_fcall_iret(&r);
}

int create_tsr(mycallback hook)
{
    _go32_dpmi_seginfo pmint8, pmint28;

#ifdef DEBUG
    owrite("cre_tsr ");
#endif
/* Locate INDOS flag */
    memset(&r, 0, sizeof(r));
    r.h.ah = 0x34;
    __dpmi_int(0x21,&r);
    if(r.x.flags&1)
    {
        printf("Unable to get indos flag\n");
        return(1);
    }
    indos_offset=(r.x.es<<4)|r.x.bx;

/* Locate Critical Error Flag */
    memset(&r, 0, sizeof(r));
    r.x.ax=0x5D06;
    __dpmi_int(0x21,&r);
    if(r.x.flags&1)
    {
        printf("Unable to get criterr flag\n");
        return(1);
    }
    critical_offset=(r.x.ds<<4)|r.x.si;

    printf( "InDos addr: 0x%x val: 0x%x\n"
        "Critical Err addr: 0x%x val: 0x%x\n",
        (int)indos_offset, _peekb(indos_offset),
        (int)critical_offset, _peekb(critical_offset));

    int_callback = hook;

/* Timer interrupt */
    _go32_dpmi_get_real_mode_interrupt_vector(TIMER_INTERRUPT,
&old_int8_vector);
    pmint8.pm_offset = (unsigned long)&myint8_function;
    _go32_dpmi_allocate_real_mode_callback_iret(&pmint8, &r);
    _go32_dpmi_set_real_mode_interrupt_vector(TIMER_INTERRUPT, &pmint8);

/* DOS idle interrupt, as DOS is primarily in this state, the */
/* indos flag could be 0x01 and we'd still be allowed to execute */
/* as long as the critical error flag is not set */
    _go32_dpmi_get_real_mode_interrupt_vector(IDLEDOS_INTERRUPT,
&old_int28_vector);
    pmint28.pm_offset = (unsigned long)&myint28_function;
    _go32_dpmi_allocate_real_mode_callback_iret(&pmint28, &r);
    _go32_dpmi_set_real_mode_interrupt_vector(TIMER_INTERRUPT, &pmint28);

    printf("*******Installing as TSR*******\n");
    __djgpp_exception_toggle(); /* Only needed if exceptions linked */
    keep(0, 0); /* Keep Transfer Buffer */
    return(0);
}

int remove_tsr()
{
/* Restore old vector, people better be removing TSR's in */
/* reverse order (as is standard in DOS behavior!) */
#ifdef DEBUG
    owrite("rem_tsr ");
#endif
    _go32_dpmi_set_real_mode_interrupt_vector(TIMER_INTERRUPT,
&old_int8_vector);
    _go32_dpmi_set_real_mode_interrupt_vector(IDLEDOS_INTERRUPT,
&old_int28_vector);

    return (0);
}
----


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019