Category : Files from Magazines
Archive   : DDJ0691.ZIP
Filename : TSR.ASC

 
Output of file : TSR.ASC contained in archive : DDJ0691.ZIP

_TAKING UP RESIDENCE WITH CODERUNNER_
by R. Bradley Andrews


[LISTING ONE]

#include "cr.h"

/** RESIDENT CODE STACK SPACE **/
#define HK_STK 150 /* Stack size for Hot-Key services */
#define SR_STK 64 /* Stack for COM services */
#define STK_SZ (HK_STK+SR_STK) /* Size in words */
word isr_stk[STK_SZ+1]; /* Allow allways extra word ! */

extern popclock(); /* Main TSR entry, called by scheduler */

extern hk_isr(); /* Hot-Key service in HELLO.C */
extern word hk_list[]; /* This is in HELLOINI.C for use by isr() function */

/******** Disposable messages in MSICLDAT.C **************/
extern char sms[]; /* Signon screen */
extern char attrc[],attrm[]; /* Screen attributes used for signon */
extern char already[]; /* Message when already loaded */
extern char unloaddone[];
extern char unloadproblem[];
extern word init_data_end; /* Marker for end of disposable data */

/* Dummy function marks start of disposable code */
init_code_start()
{
}


/* this main is called only once on program load, after that it is discarded */
main()
{ int i;
char *a;

if(second_load()) /* Check if TSR already loaded */
{
i=str_pos('-',cmd_line);
if (i && ((cmd_line[i]|0x20)=='r'))
{
if(remove_tsr()) /* Remove TSR from memory */
{
dspf(unloaddone); /* Inform about unloading */
}
else dspf(unloadproblem); /* Inform about unloading */
}
else dspf(already); /* Otherwise show Help message */
mv_crs(); /* Reposition real cursor */
return(1); /* Exit with errorlevel 1 */
}

/***** Display Signon Screen *****/
clr_scr();
a = color ? attrc:attrm; /* Select proper screen attributes */
crs_x=20; crs_y=7; /* Location to put signon box */
dspf(sms,a); /* Show the screen */

crs_x=0; crs_y=scr_len-2; /* Move to the bottom of screen */
mv_crs(); /* Place real cursor there */
crs_y=0; /* Top line used to display clock */

idata_end=&init_data_end; /* This enables init data disposal. */
icode_beg=init_code_start; /* This enables init code disposal. */

stay_resident(isr_stk,STK_SZ*2); /* Enable resident mode */
install_hk(hk_list,hk_isr,STK_SZ*2,0x7F); /* HOT-KEY Support */

install_tsc(popclock,2*STK_SZ,1); /* Install tiny scheduler */
/* add_tsc_event(8L); /* Add event to timer, 8 ticks from now */
/* Popclock will be called by scheduler */
return(0); /* Set errorlevel to 0 */

}



[LISTING TWO]

/* this module contains ALL disposable data only. The marker at the end
called init_end_data is just a marker to the end of disposable data
NO CODE CAN BE PUT INTO THIS MODULE, DATA ONLY */

#include "cr.h"

/* Video attributes for signon screen. The last one is for the Clock */

/*char attrc[]={0x17,0x1E,0x13,0x1F,0x1B,0x17}; /* Color screen attributes */
/*char attrm[]={0x07,0x0F,0x07,0x07,0x07,0x70}; /* Mono screen attributes */

/* This is the signon message */
char sms[]= "`0"
"[_________________________[`m"
"[`1 Timer 1.00 `0[`m"
"[`2 DDDDDDDDDDD `0[`m"
"[`4 Author: `0[`m"
"[`4 R. Bradley Andrews `0[`m"
"[\\\\\\\\\\\\\\\\\\\\\\\\\[`n`5";

char already[]="`nError - Timer already present."
"`nEnter MSICLOCK -R to unload.`n";
word hk_list[]={M_RS+0x44,0}; /* Right-Shift Enter */

char unloaddone[]="Timer has been removed from memory.`n";
char unloadproblem[]="Timer could not be removed from memory.";
char _tsr_name[]="Timer";

struct cfg_rec config_block = { /* This record stays in only one module */
sizeof(config_block), /* Configuration block size */
'T','I','M','E', /* Program ID string */
100, /* Version 1.00 */
};

/**** STORE THIS IMMEDIATELY AFTER THE LAST DISPOSABLE DATA ITEM ****/

/**** 1. Store all install_?? type function pointers into install_list ****/
fp install_list[]={install_tsc, install_hk, install_bk}; /* Only tiny scheduler used */

/**** 2. Put Marker for the end-of-init-data (must be = NONZERO) ****/
word init_data_end=1;
/************************************************************************/



[LISTING THREE]

#include "cr.h"

/** RESIDENT CODE STACK SPACE **/
#define HK_STK 150 /* Stack size for Hot-Key services */
#define SR_STK 100 /* Stack for COM services */
#define STK_SZ (HK_STK+SR_STK) /* Size in words */

#define kWidth 13 /* width of display string */

char time_str[]=" 00:00:00:00 ";
char blank_str[]=" ";

word sbuf[kWidth];

char attrc[]={0x17,0x1E,0x13,0x1F,0x1B,0x17}; /* Color screen attributes */
char attrm[]={0x07,0x0F,0x07,0x07,0x07,0x70}; /* Mono screen attributes */

long start_ticks;


int which=0;

popclock(void)
{ register char *t,*s;
register long cur_ticks;
struct time_rec cur_time;

if (which==1) {
add_tsc_event(1L); /* Setup next event in 1/3 second */
}
cur_ticks = bios_ticks();
cur_ticks = cur_ticks - start_ticks;
ticks2time(cur_ticks, &cur_time);

t=&cur_time.hours; /* Prepare to convert hh:mm:ss */
s=time_str+1;
do cv_b2dec((byte)*t,s), s+=3; /* Convert 1 byte to decimal */
while (--t>=&cur_time.sec100); /* Until done with seconds */

chk_video(); /* Obtain current video settings */
crs_x=scr_width-kWidth; /* Set cursor to upper right corner */
dsp(time_str); /* Display time string there */

}
hk_isr()
{
if (!which) {
crs_x=scr_width-kWidth; /* Set cursor to upper right corner */
get_block(kWidth,1,sbuf);
start_ticks = bios_ticks();
add_tsc_event(1L); /* Add event to timer, 8 ticks from now */
which++;
}
else {
if (which == 1 ) {
which++;
}
else {
crs_x=scr_width-kWidth; /* Set cursor to upper right corner */
put_block(kWidth,1,sbuf);
which = 0;
}
}
}




[LISTING FOUR]

REM Use switch d for debug mode
REM
if %1x==dx goto compdebug
tcc -c -I..\ -DPDK1 timer*.c
goto linkit
rem
:compdebug
tcc -c -v -I..\ -DDBG timer*.c
:linkit
del timerini.lib
lib timerini +timerini;
if %1x==dx goto dbg
:lnk1
link ..\r0 timerdat timer ..\r1,timer,,..\k1 ..\cr timerini/NOI/NOD/M;
goto exit
:dbg
tlink ..\r0 timerdat timer ..\r1,timer,,..\cr timerini/c/m/v;
:exit