Printer Porta Bağlanan Klavye


DOS ortamında, PC printer portundaki 5 giriş pini (10,11,12,13,15 numaralı pinler) kullanarak, PC klavyesindeki tuşları emule edebilecek, 16 tuşlu bir klavye nasıl yapılabilir? Aşağıda bahsedeceğim sistem bu soruya cevap vermek için yapıldı. Kullanım alanı epey geniş olmasına rağmen hiç bir sistemde kullanılamadı ama DOS ve PC hardware programlama konusunda iyi bir örnek olduğunu düşünüyorum.

Bu sistemi DOS ortamında çalışacak şekilde yaptım. Çünkü 1996 yılında Windows programcısı değildim. PC printer portunu kullandım çünkü bu şekilde çok az elektronik komponent kullanılarak sonuç alınabiliyor. PC klavyesini emule edecek bir sistem tasarladım çünkü bu klavye olmadan da uygulamaların çalısmasını test edebilmek istedim.

Sistem şu şekilde çalışıyor:
Bir 27512 epromu 16'dan 4'e çözücü olarak kullanıyoruz. Epromun address bus'ı tuş takımına ve data bus'ının 4 bitide printer porta bağlanıyor. Epromun data bitlerinden birinide printer portun IRQ ucu olan 10 numaralı pine bağlıyoruz ki tuşa her basıldığında oluşan IRQ ile PC klavye buffer'ına karakter kodlarını yazabilelim. Aşağıdaki tabloyu kullanarak epromun 16 adresini programlıyoruz.

Pin  Desc   Address   Data(Binary)    Data(Decimal)     Key 
---------------------------------------------------------------
 10    A0         1      00010000         16+0          '1' 
  9    A1         2	 00010001	  16+1          '2'
  8    A2         4      00010010	  16+2		'3'
  7    A3         8      00010011         16+3              (F1)
  6    A4        16      00010100	  16+4          '4'
  5    A5        32	 00010101         16+5          '5'
  4    A6	 64      00010110         16+6          '6'
  3    A7       128      00010111         16+7              (Yukarı)
 25    A8       256      00011000         16+8          '7'
 24    A9       512      00011001         16+9          '8'
 21   A10      1024      00011010         16+10         '9' 
 23   A11      2048      00011011         16+11             (Aşağı)
  2   A12      4096      00011100         16+12         #32 (Space) 
 26   A13      8192      00011101         16+13         '0'
 27   A14     16384      00011110         16+14         #13 (Enter)
  1   A15     32768      00011111	  16+15         #27 (Esc)

Diger adreslere de 0 yazdığımız zaman epromun programlanması işi bitiyor. Eproma yazılacak dosyayı üreten kod:

------------------- BEGIN EPROM FILE GENERATOR CODE --------------------

{$A-,B-,D-,E-,F-,G-,I+,L-,N-,O-,P-,Q-,R-,S-,T-,V-,X-}
{$M 16384,0,655360}

{ Eprom file generator for 16Key }

const
     FName : string = '27512.Dat';

var
   F    : file;
   I    : byte;
   Buf  : array[1..2048] of byte;
   A    : byte;
begin
 FillChar(Buf,SizeOf(Buf),#0);
 Assign(F,FName);
 {$I-}
 ReWrite(F,1);
 for I := 1 to 32 do BlockWrite(F,Buf,SizeOf(Buf));

 A := 0 + 16;
 Seek(F,65535 - 1);
 BlockWrite(F,A,SizeOf(A));

 A := 1 + 16;
 Seek(F,65535 - 2);
 BlockWrite(F,A,SizeOf(A));

 A := 2 + 16;
 Seek(F,65535 - 4);
 BlockWrite(F,A,SizeOf(A));

 A := 3 + 16;
 Seek(F,65535 - 8);
 BlockWrite(F,A,SizeOf(A));

 A := 4 + 16;
 Seek(F,65535 - 16);
 BlockWrite(F,A,SizeOf(A));

 A := 5 + 16;
 Seek(F,65535 - 32);
 BlockWrite(F,A,SizeOf(A));

 A := 6 + 16;
 Seek(F,65535 - 64);
 BlockWrite(F,A,SizeOf(A));

 A := 7 + 16;
 Seek(F,65535 - 128);
 BlockWrite(F,A,SizeOf(A));

 A := 8 + 16;
 Seek(F,65535 - 256);
 BlockWrite(F,A,SizeOf(A));

 A := 9 + 16;
 Seek(F,65535 - 512);
 BlockWrite(F,A,SizeOf(A));

 A := 10 + 16;
 Seek(F,65535 - 1024);
 BlockWrite(F,A,SizeOf(A));

 A := 11 + 16;
 Seek(F,65535 - 2048);
 BlockWrite(F,A,SizeOf(A));

 A := 12 + 16;
 Seek(F,65535 - 4096);
 BlockWrite(F,A,SizeOf(A));

 A := 13 + 16;
 Seek(F,65535 - 8192);
 BlockWrite(F,A,SizeOf(A));

 A := 14 + 16;
 Seek(F,65535 - 16384);
 BlockWrite(F,A,SizeOf(A));

 A := 15 + 16;
 Seek(F,65535 - 32768);
 BlockWrite(F,A,SizeOf(A));

 Close(F);
end.

--------------------- END EPROM FILE GENERATOR CODE -------------------

DOS ortamında bu sistemi çalıştırmak için bir TSR program olması gerekiyor. Bu kod aşağıda.

------------------------ BEGIN DRIVER CODE -----------------------------

{$A-,B-,D-,E-,F-,G-,I-,L-,N-,O-,P-,Q-,R-,S-,T-,V-,X-}
{$M 1024,0,0}

program 16KDrv;

uses Crt,Dos;

var
   OldInt  : procedure;
   BaseAdr : word absolute $0000:$0408;

function ReadKB(var Key:byte):boolean;
var
   A : byte;
begin
 Key := 0;
 A := Port[BaseAdr + 1];
 if (A and 32) <> 0 then Key := Key or 1;
 if (A and 16) <> 0 then Key := Key or 2;
 if (A and 8) <> 0 then Key := Key or 4;
 if (A and 128) = 0 then Key := Key or 8;
 ReadKB := (A and 64) <> 0;
end;

(*
 { Direct access to KeyBoard Buffer }
procedure Write2KBuf(C: char);
var
   KBuffer  : array[0..15] of word absolute $0000:$041E;
   Tail     :                 word absolute $0000:$041C;
   Head     :                 word absolute $0000:$041A;
begin
 if Tail + 2 = Head then
  begin
   Sound(1000);
   Delay(100);
   NoSound;
   Exit;
  end;
 KBuffer[(Tail div 2) - 15] := byte(C);
 Inc(Tail,2);
 if Tail > 60 then Tail := 30;
end;
*)

procedure Beep;
begin
 Sound(1000);
 Delay(100);
 NoSound;
end;

procedure Write2KBuf(W: word);assembler;
asm
        mov ah,05h
        mov cx,W
        int 16h
        and al,al
        jz @Quit
        call Beep
@Quit:
end;

{$F+}
procedure NewInt;interrupt;
const
     CTable : array[0..15] of word =
      (48 + 1  +  256 * 2,
       48 + 2  +  256 * 3,
       48 + 3  +  256 * 4,
       8       +  256 * 14,
       48 + 4  +  256 * 5,
       48 + 5  +  256 * 6,
       48 + 6  +  256 * 7,
       0       +  256 * 72,
       48 + 7  +  256 * 8,
       48 + 8  +  256 * 9,
       48 + 9  +  256 * 10,
       0       +  256 * 80,
       32      +  256 * 57,
       48 + 0  +  256 * 11,
       27      +  256 * 1,
       13      +  256 * 28);
var
   Key      : byte;
begin
 InLine($FB); { Sti }
 Delay(20);
 if ReadKB(Key) then Write2KBuf(CTable[Key]);
 InLine($FA); { Cli }
 Port[$20] := $20;  { Reset the 8259 PIC }
 asm
        PushF
        Call OldInt
 end;
end;
{$F-}

begin
 ClrScr;
 Port[BaseAdr + 2] := Port[BaseAdr + 2] or 16; (Enable PRN IRQ)
 Port[$21] := $00; 
 Port[$20] := $20; (Unmask IRQ #7)
 GetIntVec($0F,@OldInt);
 SetIntVec($0F,@NewInt);
 Keep(0);
end.

---------------------------- END DRIVER CODE----------------------------

Bu klavyeyi likit kristal ekranla beraber kullanma şansımız var. Çünkü printer portun sadece 5 giriş pinini kullandık. Likit kristal ekransa 8 data biti ve 2 kontrol biti daha gerektiriyor ki zaten printer portta bu kadar boş yer var. İki sistem bir arada kullanıldığında geriye bilgisayarın geriye sadece kasası kalıyor.

Yazılım olarak en büyük eksiği sadece DOS ortamında çalışıyor olması. Eğer sürücü TSR yerine bir vxd yazılırsa Windows ortamında da çalışması mümkün ama bunu yapmak için kullanılacağı bir yer bulmak şart.


[ sayfa başı ] [ ana sayfa ] [ projeler ] [ programlar ] [ şarkılar ] [ linkler ] [ e-mail ]
Hosted by www.Geocities.ws

1