interrupt handling und PIC. Wie mach ichs richtig?
-
Das sind für einen ders weiß bestimmt leichte Fragen aber ich hab im Internet nix so wirklich befriedigendes gefunden. Ich würde mal folgendes gerne wissen:
1. Über den PIC. Ich möchte z.B. Tastatur auf irq 1 legen und z.B. fdc auf irq 2 wie geht das?2. Ganz einfach: Ich hab nen Interrupthandler geschrieben und möchte das der abgearbeitet wird, wenn irq 1 ausgelöst wird. Wie mache ich das? Da hab ich zwar was drüber gefunden aber das blick ich nich so ganz
3.Noch eine ganz besoders dumme Frage (aber wer nicht fragt bleibt ja bekanntlich dumm ;)) was macht der asm-befehl int so genau? Was passiert zum beispiel wenn ich int 36h oder so ausführe (bzw. woher weiß der Prozessor welchen code er in diesem Falle auszuführen hat?).
-
Hi.
Zu 1:
Welchen IRQ die Hardware belegt haengt nicht vom PIC, sondern von der entsprechenden Hardware selbst ab.
zB. kannst du den IRQ der Tastatur (IRQ1), des Floppy Disk-Controllers (IRQ2) oder des Systemzeitgebers (IRQ0) nicht veraendern (kannst es in Windows zB. ueber die Systemsteuerung mal ausprobieren - da beschwert es sich).
Zu 2:
Erst einmal musst du den Interrupthandler in die Interrupttabelle eintragen. Wie das genau geht haengt nun vom Prozessormodus (RM/PM) ab, bzw. welche Basisinterrupts im Primary/Secondary PIC eingestellt sind... (Im RM ist das beim Primary PIC Int 8 (dh. bei IRQ 0 wird int 8 aufgerufen bei IRQ 1 int 9 usw.) und beim secondary int 70h (IRQ 8 => int 70h usw.)
Danach muessen die entsprechenden IRQs nur noch im PIC eingeschaltet werden und fertig ist.
Letzteres geht folgendermassen:
Fuer primary PIC (IRQ0-7):
Port 21h: Bit0=> IRQ0
Bit1=> IRQ1
usw...
Wenn Bits auf 0 gesetzt werden, ist der enstsprechende IRQ aktiviert.
Fuer secondary PIC gilt das gleiche fuer IRQs 8 bis 15.
Der secondary PIC wird ueber Port A1 angesprochen.Zu 3:
Was da nun genau ablaeuft, haengt wieder hauptsaechlich vom Prozessormodus ab.
Grundsaetzlich wird aber eine Zieladdresse aus der Interrupttabelle beim Index, der mit dem Int-Befehl uebergeben wird, ausgelesen.
Anschliessend werden die Flags auf dem Stack abgelegt und ein FAR-call zu der aus der Interrupttabelle ausgelesenen Addresse ausgefuehrt.[edit]In den FAQ gibt es bei den OS-Dev Links auch noch weitere Informationen ueber den PIC...[/edit]
-
Ok ich seh schon. Also gehen wir für fragestellung 2 u. 3. vom Real Mode aus.
und zu 1. Ich dachte immer es heißt programmable interrupt controller, da man ihn selbst programmieren kann aber belehre mich eines besseren.
-
Jo, das Ding ist auch ziemlich umfassend programmierbar. zB. in Hinsicht auf die Prioritaet mit der die einzelnen IRQs abgehandelt werden, usw.
Dazu kennt die CPU an sich keine IRQs, sondern hat nur einen Pin, ueber den alle IRQs angekuendigt werden - den Rest handelt der PIC.
Die IRQs kann man AFAIK aber trotzdem nicht einfach durcheinanderwuerfeln, wie man lustig ist.Dann nochmal ausfuehrlicher zu Interrupts im RM:
Die Interrupttabelle liegt hier bei 0000:0000.
Dort liegt zuerst ein DWord mit der Far-Addresse (erstes word Offset; zweites word Segment) zu int 0.
Das naechste DWord (Addr. 0000:0004) enthaelt nun die Addresse zu int 1.
usw.
Insgesamt enthaelt die Interrupttabelle 256 solcher Eintraege, dh. Interrupts von 00h bis FFh.Da nun im RM der Primary PIC so eingerichtet ist, dass der Basisinterrupt int 8 ist, musst du um einen neuen Handler fuer IRQ 1 einzurichten int 9 (Basisinterrupt 8 + IRQ 1) veraendern.
Dh. Du musst bei Addresse 0000:0024 (4(fuer DWord)*9(Interruptnummer)) die Far-Addresse deines Handlers eintragen.Nun musst du wie gesagt noch IRQ 1 im Primary PIC einschalten.
;Beispielcode zum Aktivieren eines IRQ im Primary PIC: in al,21h ;IRQ Mask vom Primary PIC einlesen mov bl,0FEh ;Binaer: 1111 1110 mov cl,[IRQNummer] ;IRQNummer (Wert zwischen 0 und 7) rol bl,cl ;Den 0Bit an die entsprechende Stelle verschieben... ;fuer IRQ 1 waere das rol bl ,1, also bl=1111 1101 ;also alle Bits 1 bis auf Bit1. and al,bl ;entsprechendes Bit aus der PIC-Mask loeschen... ;=>bei IRQ1 wird nur Bit1 auf 0 gesetzt. Der Rest wird nicht beeinflusst... out 21h,al
BTW: Nicht vergessen im IRQ-Handler die Ausfuehrung des IRQ beim PIC zu bestaetigen. Beispiel fuer Primary PIC:
mov al,20h out 20h,al
Bei einem IRQ, der vom Secondary PIC ausgeloest wird (IRQs 8 bis 15) muss der IRQ beim Primary und secondary PIC bestaetigt werden:
mov al,20h out 20h,al out 0A0h,al
Im RM passiert ansonsten beim Aufruf eines int-Befehls lediglich das, was ich schon geschrieben habe.
Dh. wenn zB. int 21h aufgerufen wird, werden die Flags auf den Stack gepusht und ein Far Call zu [0000:0084] (0000:4*21h) ausgefuehrt.
-
Danke. So schwer is das ja alles garnich