Pascal'da Interrupt 16h (Keyboard Interrupt) nasıl programlanır?
Pascal programlama dilinde zor gibi görülen TSR programlamanın temel mantığını anlatmaktadır. Örnek olarak programlanması dikkatli yapılması gereken interruptlardan Int 16h (Keyboard Intterrupt) seçilmiştir.(*
* TSR Interrupt 16h (Keyboard Interrupt)
*
* Program; Interrupt 16h'e kanca atar, girilen tuşların kodlarını ekranda
* görüntüler.
*
* [email protected]
*
*)
uses DOS, Crt;
{$F+}
var
Int16Handler: Pointer; { Önceki Int 16h adresi }
procedure Int16(_Flags, _CS, _IP, _AX, _BX, _CX, _DX, _SI, _DI,
_DS, _ES, _BP: Word); interrupt;
label
__Int16Ret;
begin
{ Aşağıdaki kısım Int 16h'nin asli görevlerini yerine }
{ getirmesi için, eğer bunlar yapılmazsa bilgisayar kilitlenir }
asm
PUSHF
{ DS segmenti eski değerine }
XCHG AX,[_DS]
MOV DS,AX
{ AX registeri eski değerine }
MOV AX,[_AX]
CMP AH,$00 { Int16h/00h? }
JZ @BasilanOgren
CMP AH,$01 { Int16h/01h? }
JZ @BasilanOgren
{ E§er di§er fonksiyonlar çağrılıyorsa doğrudan }
{ eski Int16h de§erine git }
MOV AX,WORD PTR [Int16Handler+2]
MOV BX,WORD PTR [Int16Handler]
MOV [_CS],AX
MOV [_IP],BX
JMP __Int16Ret
@BasilanOgren:
{ Basılan tuşlar önceki Int16 çağrılarak öğreniliyor }
CALL DWORD PTR [Int16Handler]
PUSHF
MOV [_AX],AX
{ DS segmenti PASCAL'ın DS segmentine dönderiliyor }
MOV AX,DS
XCHG AX,[_DS]
MOV DS,AX
MOV AX,[_AX]
end;
{ E§er AL=0 ise bir fonksiyon tuşuna basıldı }
if (Lo(_AX) = 0) then
begin
TextColor(White);
Write(Hi(_AX):5);
end
else
begin
TextColor(Yellow);
Write(Lo(_AX):5);
end;
{ Interrupt'tan artık çıkılıyor }
__Int16Ret:
inline($9D); { POPF }
end;
{$F-}
begin
ClrScr;
GetIntVec($16, Int16Handler);
SetIntVec($16, @Int16);
WriteLn('Interrupt 16h TSR Program Örneği');
WriteLn;
WriteLn;
WriteLn('Lütfen bir tuşa basınız (ESC=Çıkış):');
Window( 1, 6, 80, 25 );
while (ReadKey <> #27) do;
SetIntVec($16, Int16Handler);
end.
Pascal programlama dilinde zor gibi görülen TSR programlamanın temel mantığını anlatmaktadır. Örnek olarak programlanması dikkatli yapılması gereken interruptlardan Int 16h (Keyboard Intterrupt) seçilmiştir.(*
* TSR Interrupt 16h (Keyboard Interrupt)
*
* Program; Interrupt 16h'e kanca atar, girilen tuşların kodlarını ekranda
* görüntüler.
*
* [email protected]
*
*)
uses DOS, Crt;
{$F+}
var
Int16Handler: Pointer; { Önceki Int 16h adresi }
procedure Int16(_Flags, _CS, _IP, _AX, _BX, _CX, _DX, _SI, _DI,
_DS, _ES, _BP: Word); interrupt;
label
__Int16Ret;
begin
{ Aşağıdaki kısım Int 16h'nin asli görevlerini yerine }
{ getirmesi için, eğer bunlar yapılmazsa bilgisayar kilitlenir }
asm
PUSHF
{ DS segmenti eski değerine }
XCHG AX,[_DS]
MOV DS,AX
{ AX registeri eski değerine }
MOV AX,[_AX]
CMP AH,$00 { Int16h/00h? }
JZ @BasilanOgren
CMP AH,$01 { Int16h/01h? }
JZ @BasilanOgren
{ E§er di§er fonksiyonlar çağrılıyorsa doğrudan }
{ eski Int16h de§erine git }
MOV AX,WORD PTR [Int16Handler+2]
MOV BX,WORD PTR [Int16Handler]
MOV [_CS],AX
MOV [_IP],BX
JMP __Int16Ret
@BasilanOgren:
{ Basılan tuşlar önceki Int16 çağrılarak öğreniliyor }
CALL DWORD PTR [Int16Handler]
PUSHF
MOV [_AX],AX
{ DS segmenti PASCAL'ın DS segmentine dönderiliyor }
MOV AX,DS
XCHG AX,[_DS]
MOV DS,AX
MOV AX,[_AX]
end;
{ E§er AL=0 ise bir fonksiyon tuşuna basıldı }
if (Lo(_AX) = 0) then
begin
TextColor(White);
Write(Hi(_AX):5);
end
else
begin
TextColor(Yellow);
Write(Lo(_AX):5);
end;
{ Interrupt'tan artık çıkılıyor }
__Int16Ret:
inline($9D); { POPF }
end;
{$F-}
begin
ClrScr;
GetIntVec($16, Int16Handler);
SetIntVec($16, @Int16);
WriteLn('Interrupt 16h TSR Program Örneği');
WriteLn;
WriteLn;
WriteLn('Lütfen bir tuşa basınız (ESC=Çıkış):');
Window( 1, 6, 80, 25 );
while (ReadKey <> #27) do;
SetIntVec($16, Int16Handler);
end.