home *** CD-ROM | disk | FTP | other *** search
- {$M 1024,0,100}
- program tsrtest; {TSR shell for Turbo Pascal 4.0 from Stephen Schneck}
- {I can be reached on Phil Grier's BBS for comments. }
- {301/498-XXXX}
- uses dos,crt; {N.b. adjust compiler memory directive for changes.}
-
-
- type
- byte2 = array[1..2] of byte;
- byte16 = array[1..16] of byte;
-
- const
- hotkey = 198; {the scroll lock key when released}
- vid_seg = $B000; {monochrome ttl screen }
- vid_off = 141; {top right screen location }
- attribute = 112; {show clock in reverse video }
- var
- z : integer;
- ch : char;
- scancode,x : byte;
- exitvector,
- new09vector,
- old09vector : pointer;
- regs : registers;
- b : byte2;
- scr_array,
- old_array : byte16;
-
-
- {$F+}
- procedure my_exit; {all-purpose exit proc modified for my kbd intercept }
- {$F-} {routine -- inspired by Neil Rubenking in PC Magazine}
- begin
- setintvec($09,old09vector); {turns off my kbd intercept routine by }
- {reseting 09 interrupt to aim at its own code}
- if (exitcode <> 0) or (erroraddr <> nil) then
- begin
- assign(output, '');
- rewrite(output);
- writeln(#7);
- begin
- write('Critical Error #',exitcode,' at address ');
- writeln(seg(erroraddr^),':',(ofs(erroraddr^)));
- end;
- end;
- exitproc := exitvector;
- end;
-
- procedure convert_from_bcd; {procedure would be smaller & speedier in asm}
- begin
- if x > 49 then begin b[1] := 53; b[2] := x - 2; end
- else if x > 39 then begin b[1] := 52; b[2] := x + 8; end
- else if x > 29 then begin b[1] := 51; b[2] := x + 18; end
- else if x > 19 then begin b[1] := 50; b[2] := x + 28; end
- else if x > 9 then begin b[1] := 49; b[2] := x + 38; end
- else begin b[1] := 48; b[2] := x + 48; end;
- end;
-
-
- procedure newint09handler(Flags,cs,ip,ax,bx,cx,dx,si,di,ds,es,bp : word);
- interrupt;
- begin
- inline($9C); {pushf }
- scancode := port[$60]; {check scan code of pressed key }
- if scancode = hotkey then {if it's our hotkey then GO!!! }
-
- {████████████ Here begins what you want to run resident. ███████████}
- {████████████ You can't use Pascal code that calls DOS. ███████████}
- {My sample code is a tsr clock. Note that I call for bios time not DOS }
- {time function. DOS time seems to be what is called in TP4's routines. }
- {You can't use these because DOS normally cannot be called from tsr }
- {programs. My computer ( Leading Edge ) gets bios time from int 1A, }
- {function 2. I believe this is a standard for the IBM-AT and most of }
- {the XT clones. Older IBMs and some clones may not support this. }
-
- begin
- for z := 1 to 16 do
- old_array[z] := mem[vid_seg:vid_off + z];
- regs.ah := $02; {set AH for bios time call (func 2) }
- intr(26,regs); {call bios clock (int 1A) }
- x := regs.ch; convert_from_bcd; {x has hours in bcd }
- scr_array[1] := b[1]; {load screen array with hours }
- scr_array[3] := b[2];
- scr_array[5] := 58;
- x := regs.cl; convert_from_bcd; {x has minutes in bcd }
- scr_array[7] := b[1];
- scr_array[9] := b[2];
- scr_array[11] := 58;
- x := regs.dh; convert_from_bcd; {x has seconds in bcd }
- scr_array[13] := b[1];
- scr_array[15] := b[2];
- for z := 1 to 16 do {write screen array to screen memory}
- mem[vid_seg:vid_off + z] := scr_array[z];
- sound(360); delay(100); nosound;
- delay(1400); {beep & delay to get human to notice}
- for z := 1 to 16 do {then restore screen as it was }
- mem[vid_seg:vid_off + z] := old_array[z];
- end;
- {████████████ Here ends what you want to run resident. ███████████}
-
- {now comes hard job of switching control back to real 09 handler }
- {the inline code is credited to somebody named Lane Ferris }
- inline(
- $9D/ {POPF ;begin exit from handler }
- $A1/> old09vector+2/ {MOV AX,KBD_VEC+2 ;get seg addr of old 09 }
- $8B/$1E/> old09vector/ {MOV BX,KBD_VEC ;get off of old 09 handler }
- $87/$5E/$0E/ {XCHG BX,[BP+14] ;restore old offset }
- $87/$46/$10/ {XCHG AX,[BP+16] ;ditto segment -- put in ax }
- $8B/$E5/ {MOV SP,BP ;undo what TP did with INTR }
- $5D/ {POP BP ;pop back all the registers }
- $07/ {POP ES}
- $1F/ {POP DS}
- $5F/ {POP DI}
- $5E/ {POP SI}
- $5A/ {POP DX}
- $59/ {POP CX}
- $CB); {RETF ;works to jmp to old 09-uses}
- end;
-
- procedure tsr;
- begin
- keep(exitcode);
- end;
-
- procedure start;
- begin
- getintvec($09,old09vector); {save the machine's 09 int handler }
- setintvec($09,@newint09handler); {aim 09 int calls to our int handler}
- exitvector := exitproc;
- exitproc := @my_exit;
- for z := 1 to 16 do
- scr_array[z] := attribute;
- end;
-
- begin
- start;
- writeln(' TSR program is active -- scroll lock is hotkey.');
- tsr;
- end.