3.15.1 Timer

Der Interrupt 83h ist wohl der Timer-Interrupt, des PV. Er wird 40 mal pro Sekunde aufgerufen und eigentlich vom Betriebssystem verwendet...
Mit Hilfe von Johannes Steingräber haben wir es geschafft, den Interrupt "anzuzapfen", d.h. Ihn gleichzeitig mit dem Betriebssystem zu nutzen - welches diesen evtl. für das weiterlaufen der Uhrzeit oder ähnliches benötigt... Die Routine des Betriebssystems zählt zumindest einen Zähler von 0 bis 39 hoch und fängt dann wieder bei 0 an... Außerdem wird der Timer wohl nur aktiviert, wenn irgendwelche Routinen, wie "Lib....Wait" aufgerufen werden, die nach einer gewissen Zeitspanne abbrechen...
Diese sollte man meiden, wenn man die "GrayLib" verwendet, da die GrayLib den Interrupt selbst aktiviert und die "Lib...Wait"-Routinen diesen wieder deaktivieren würden - man kann ihn natürlich auch einfach wieder aktivieren...

Folgende Assembler-Datei "hängt" sich in den Int 83h ein:


Datei "intproc.a86":
--------------------
; intproc
;
INTNR EQU 83h

DATA DSEG
counter_:: dw 0 ; public (global) variable "counter"
oldintvec: dw 0,0 ; old interrupt vector

intproc_TEXT CSEG

.186

newintproc:
push ax ; dummy for retf address
push ax ; dummy for retf address

push bp
mov bp,sp
push ax
push ds
pushf

mov ax,DATA
mov ds,ax

inc [counter_].w

mov ax,[oldintvec]
mov [bp+2],ax
mov ax,[oldintvec+2]
mov [bp+4],ax

popf
pop ds
pop ax
pop bp

retf ; this will pop the two dummy pushes

setintvec_::
push ax
push es
pushf
cli
xor ax,ax
mov es,ax
mov ax,es:[INTNR*4]
mov [oldintvec],ax
mov ax,es:[INTNR*4+2]
mov [oldintvec+2],ax
mov ax,newintproc
mov es:[INTNR*4].w, ax
mov ax,cs
mov es:[INTNR*4+2].w, ax
popf
pop es
pop ax
retf


resetintvec_::
push ax
push es
pushf
cli
xor ax,ax
mov es,ax
mov ax,[oldintvec]
mov es:[INTNR*4],ax
mov ax,[oldintvec+2]
mov es:[INTNR*4+2],ax
popf
pop es
pop ax
retf 
Datei "IntTest.c":
------------------

#include 
#include "libc.h"
#include "L_libc.h"

extern unsigned int counter;

extern far setintvec(); 
extern far resetintvec();

void _asm_fastinton(char *);
void _asm_fastintoff(char *);
#define FastIntOn() _asm_fastinton("n IN AX,0Ahn AND AX,0FFF7hn OUT 0Ah,AXn IN AX,08hn OR AX,0008hn OUT 08h,AXn IN AX,0Ahn OR AX,0008hn OUT 0Ah,AXn");
#define FastIntOff() _asm_fastinton("n IN AX,0Ahn AND AX,0FFF7hn OUT 0Ah,AXn IN AX,08hn AND AX,0FFF7hn OUT 08h,AXn");


void main () {
setintvec(); /* "hängt" sich in den Interrupt 83h ein */
FastIntOn(); /* schaltet den Timer ein - damit er auch aufgerufen wird... */
.
.
/* Beispiel: */

counter=0; /* Stellt den Timer-Counter zurück */
do { } while (counter<40); /* Wartet bis der Timer 40 mal eine 1/40 Sekunde gezählt hat (dauert 1 Sekunde) */

/* ENDE des Beispiels */
.
.
FastIntOff(); /* schaltet den Timer ein - damit er auch aufgerufen wird... */
resetintvec(); /* stellt den Originalzustand wieder her */

LibJumpMenu(); /* Beendet die PV-Applikation */
}

Für Ergänzungen wenden Sie sich bitte an: Jürgen Wagner