Board index » delphi » Interrupt Clock (Can't WRITE to disk)

Interrupt Clock (Can't WRITE to disk)

It could be that GetTime uses Dos calls which are not re-entrant.
What happens when you remove GetTime and fill the registers yourself ?

Greetings,
ASS-Ware
--
           ,,,
          (o o)
 -----oOO--(_)--OOo-----
|       ASS-Ware        |
|    is watching you    |
 -----------------------

Neil Jaques <n...@jhome.demon.co.uk> wrote in article
<lm+7lCAeZKlyE...@jhome.demon.co.uk>...

Quote
> I recently decided to add a clock to my database, I am designing, one
> that uses interrupts instead of loops.
> Now the problem is that it seems to be conflicting with writing to the
> A: and the computer totally hangs, you can't CTRL-BREAK, or even Warm
> Boot the computer.
> I would appreciated any help in this matter and below I have enclosed my
> code, which I obtained form this newsgroup along time ago.

> {$F+,S-,W-}
> PROCEDURE Timehandler; INTERRUPT;
> VAR       i, x, y            : Byte;
>           Offset             : WORD;
>           TheTime            : String[8];
>           qTime              : String[8];
>           Hr, Min, Sec, Hund : WORD;
>           H, M, S            : String[2];
> BEGIN
>      x := 5;
>      y := 2;
>      Offset := ((y-1)* 80 + (x-1))* 2;
>      GetTime(Hr,Min,Sec,Hund);
>      STR(Hr:0, H);
>      IF Length(H) = 1
>         THEN H := '0' + H;

>      STR(Min:0, M);
>      IF Length(M) = 1
>         THEN M := '0' + M;

>      STR(Sec:0, S);
>      IF Length(s) = 1
>         THEN S := '0' + S;

>      qTime := H + ':' + M + '.' + S;
>      FOR I := 1 TO Length (qTime) DO
>      BEGIN
>           MemW[$b800:Offset]:= (TheAttribute Shl 8) + Ord (qTime [i]);
>           Inc (Offset, 2);
>      END;
> END;
> {$F-,S+}

> This is the main bit of code, which is probably causing the problem.
> If anybody has any soltutions then please speak up.

> Thanx in advance
>  __  _     _ _  _____
> |  \| |___(_) |(_   _) _ __ _ _ _ ___ ____
> |     | -_) | | _| | _` | _` | | | -_) ___/
> |_|\__|___|_|_|(___/__,_|__, |___/___|_  |
> n...@jhome.demon.co.uk      \____________/
> http://www.jhome.demon.co.uk/neil/neil.htm                      

 

Re:Interrupt Clock (Can't WRITE to disk)


I recently decided to add a clock to my database, I am designing, one
that uses interrupts instead of loops.
Now the problem is that it seems to be conflicting with writing to the
A: and the computer totally hangs, you can't CTRL-BREAK, or even Warm
Boot the computer.
I would appreciated any help in this matter and below I have enclosed my
code, which I obtained form this newsgroup along time ago.

{$F+,S-,W-}
PROCEDURE Timehandler; INTERRUPT;
VAR       i, x, y            : Byte;
          Offset             : WORD;
          TheTime            : String[8];
          qTime              : String[8];
          Hr, Min, Sec, Hund : WORD;
          H, M, S            : String[2];
BEGIN
     x := 5;
     y := 2;
     Offset := ((y-1)* 80 + (x-1))* 2;
     GetTime(Hr,Min,Sec,Hund);
     STR(Hr:0, H);
     IF Length(H) = 1
        THEN H := '0' + H;

     STR(Min:0, M);
     IF Length(M) = 1
        THEN M := '0' + M;

     STR(Sec:0, S);
     IF Length(s) = 1
        THEN S := '0' + S;

     qTime := H + ':' + M + '.' + S;
     FOR I := 1 TO Length (qTime) DO
     BEGIN
          MemW[$b800:Offset]:= (TheAttribute Shl 8) + Ord (qTime [i]);
          Inc (Offset, 2);
     END;
END;
{$F-,S+}

This is the main bit of code, which is probably causing the problem.
If anybody has any soltutions then please speak up.

Thanx in advance
 __  _     _ _  _____
|  \| |___(_) |(_   _) _ __ _ _ _ ___ ____
|     | -_) | | _| | _` | _` | | | -_) ___/
|_|\__|___|_|_|(___/__,_|__, |___/___|_  |
n...@jhome.demon.co.uk      \____________/
http://www.jhome.demon.co.uk/neil/neil.htm                      

Re:Interrupt Clock (Can't WRITE to disk)


In article <lm+7lCAeZKlyE...@jhome.demon.co.uk>

Quote
Neil Jaques wrote:
>I recently decided to add a clock to my database, I amdesigning, one
>that uses interrupts instead of loops.
>Now the problem is that it seems to be conflicting withwriting to the
>A: and the computer totally hangs, you can't CTRL-BREAK, oreven Warm
>Boot the computer.
>I would appreciated any help in this matter and below I haveenclosed my
>code, which I obtained form this newsgroup along time ago.

>{$F+,S-,W-}
>PROCEDURE Timehandler; INTERRUPT;
>VAR       i, x, y            : Byte;
>          Offset             : WORD;
>          TheTime            : String[8];
>          qTime              : String[8];
>          Hr, Min, Sec, Hund : WORD;
>          H, M, S            : String[2];
>BEGIN
>     x := 5;
>     y := 2;
>     Offset := ((y-1)* 80 + (x-1))* 2;
>     GetTime(Hr,Min,Sec,Hund);
>     STR(Hr:0, H);
>     IF Length(H) = 1
>        THEN H := '0' + H;

>     STR(Min:0, M);
>     IF Length(M) = 1
>        THEN M := '0' + M;

>     STR(Sec:0, S);
>     IF Length(s) = 1
>        THEN S := '0' + S;

>     qTime := H + ':' + M + '.' + S;
>     FOR I := 1 TO Length (qTime) DO
>     BEGIN
>          MemW[$b800:Offset]:= (TheAttribute Shl 8) + Ord(qTime [i]);
>          Inc (Offset, 2);
>     END;
>END;
>{$F-,S+}

>This is the main bit of code, which is probably causing theproblem.
>If anybody has any soltutions then please speak up.

Hello Neil,

You don't say what interrupt you are intercepting.  If you
are trapping $1C or $08.  If int $1C, then it might not
matter that you are not calling the previous handler.  But
if $08, then you are probably disabling critical parts of
the OS.

Another possible problem concerns the amount of time you spend
in your routine.  If your machine isn't fast enough to
complete the task before the next tic, the OS would have to
call your routine again. Eventually this would cause your
system to hang.  I doubt the failure would be from a stack
overflow, but more likely due to the system running out of
interrupt stacks.

Since your routine affects the entire system, you should
try to make it as efficient as possible.

First you might consider that you are executing your code
a tad more than 18 times a second, yet it for all its work
it displays the save value 17 times.  Consider saving seconds
in a local const and skip the rest of the routine if there
is no change from the last time.

Next you might consider replacing the string concatenation
with a method that builds the string "in-place".

This is where a little assembler can help.  Consider the
following:

CONST Ten : Byte = 10;   {12345678}
      Time: String[8] := '00:00:00';

    mov AL,[Sec]
    xor AH,AH
    div [Ten]                  { AL=Tens, AH=Units       }
    or  3030h                  { convert to ASCII digits }
    mov AX, WORD PTR [Time+7)

If you are ever concerned about taking too much time in a
hardware interrupt service routine, define a local const,
maybe call it Entered or Active and set it to zero.  If
timing is really critical, you should use assembly language
to set the semaphore.  On the 80x86 the XCHG instruction
locks the bus until completion.  Thus

    mov   AL,1
    XCHG  [active],AL
    or  AL,AL
    jnz @Skip     ; exit if we didn't set the semaphore

    -- perform task ---

    mov   [active],0 ; we are the owner, so release semaphore

@Skip:

If you don't have too critical a timing problem, you might be
able to get away with something like ---

    Inc(Active);
    If Active = 1 Then Begin

       -- perform task ---

    End;
    Dec(Active);

Regardless of whether you implement any of the above, you
need to call the previous interrupt service routine. Define
your routine as receiving parameter FLAGS: Word, and define
the OldIsr as a Procedure variable that receives a word.  
Then you can invoke it from Pascal as OldIsr(Flags);

From assembler you can call the OldIsr using:

     pushf
     call  DWORD PTR [OldIsr]

Hope some of this helps.

    ...red

Other Threads