#include #include #include #define DATA_A 0x4f1c /* Adresser til 8255A */ #define DATA_B 0x4f1e #define DATA_C 0x5f1c #define KNTR8255 0x5f1e #define INTR_A00 0x20 #define INTR_A01 0x21 #define EOI_8259 0x20 /* EOI til 8259A */ #undef inportb() /* Bruk I/O-funksjoner, */ #undef outportb() /* gir I/O forsinkelse */ long teller; /* Felles teller */ int lest; /* Lest fra bryterne */ /* Deklarasjoner */ void near init8255(void); void interrupt skriv_port_b(); /* Betjener port B */ void interrupt les_port_a(); /* Betjener port A */ main() { int irr,isr,imr; /* Status reg. 8259 */ int gammel_imr; /* Lager for imr-reg. */ int st; /* Status reg 8255 */ void interrupt (*gammelint15)(); /* IRQ7 Data ut */ void interrupt (*gammelint11)(); /* IRQ3 Data inn */ long i; init8255(); disable(); /* Slå av avbrudd */ gammel_imr = inportb(INTR_A01); /* Muliggjør IRQ3 og 7 */ outportb(INTR_A01,gammel_imr & 0x77) ; gammelint11 = getvect(11); /* Bevar avbruddsvektorer */ gammelint15 = getvect(15); setvect(15,skriv_port_b); /* Avbruddsvektorene på plass */ setvect(11,les_port_a); enable(); /* Hovedprogrammet. Løkke som leser status og øker teller med 1 */ clrscr(); do { outportb(INTR_A00,0x0a); /* Les "Interrupt Request Reg." */ irr = inportb(INTR_A00); outportb(INTR_A00,0x0b); /* Les "In-Service Register" */ isr = inportb(INTR_A00); imr = inportb(INTR_A01); /* Les "Interrupt Mask Reg." */ st = inportb(DATA_C); /* Les 8255A status register */ /* Skriv til skjermen */ gotoxy(2,10); cprintf("Fra main: irr= 0x%02x isr= 0x%02x imr= 0x%02x st= 0x%02x\n", irr,isr,imr,st); teller = teller +1; gotoxy(62,10); cprintf("teller: 0x%04x\n",teller); for(i=1; i<=1200000l; i++); /* Venteløkke */ }while(kbhit() == 0); /* Avslutt: trykk på tast */ getch(); /* Tøm lesebuffer */ /* Rydd opp for retur til MS-DOS */ disable(); setvect(11,gammelint11); /* Originale vektorer tilbake */ setvect(15,gammelint15); outportb(INTR_A01,gammel_imr); /* Original imr tilb. til 8259A */ enable(); } /* Betjeningsrutine for IRQ7. Skriver "teller" til lysdiodene */ void interrupt skriv_port_b() { int irr,isr,imr,st; int i; long j; outportb(DATA_B,teller); /* Skriv til lysdiodene */ enable(); /* Muliggjør andre avbrudd */ for(i=1; i<=10; i++) /* Teller til 10 før retur */ { outportb(INTR_A00,0x0a); /* Les status på 8259 */ irr = inportb(INTR_A00); outportb(INTR_A00,0x0b); isr = inportb(INTR_A00); imr = inportb(INTR_A01); st = inportb(DATA_C); /* Les status på 8255A */ gotoxy(2,14); cprintf("Fra IRQ7 (skriv) irr= 0x%02x isr= 0x%02x imr= 0x%02x\ st= 0x%02x\n", irr,isr,imr,st); gotoxy(62,14); cprintf("teller: 0x%04x\n",teller); teller = teller +1; for(j=1;j<=1200000l;j++); } disable(); outportb(INTR_A00,EOI_8259); /* Send EOI til 8259 */ } /* Betjeningsrutine for IRQ3. Leser fra bryterne, teller oppdateres */ void interrupt les_port_a() { int irr,isr,imr,st; int i; long j; lest = inportb(DATA_A); /* Les bryterne */ enable(); Muliggjør avbrudd igjen */ teller = lest; /* Oppdater teller */ for(i=0; i<=10; i++) /* Teller til 10 før retur */ { outportb(INTR_A00,0x0a); /* Les status på 8259 */ irr = inportb(INTR_A00); outportb(INTR_A00,0x0b); isr = inportb(INTR_A00); imr = inportb(INTR_A01); st = inportb(DATA_C); /* Les status på 8255A */ gotoxy(2,12); cprintf("Fra IRQ3 (les) irr= 0x%02x isr= 0x%02x imr= 0x%02x\ st= 0x%02x\n", irr,isr,imr,st); gotoxy(62,12); cprintf("teller: 0x%04x\n",teller); teller = teller +1; for(j=1; j<=1200000l; j++); } disable(); outportb(INTR_A00,EOI_8259); /* Send EOI til 8259 */ } void near init8255() { int j; outportb(KNTR8255,0xb4); /* Mode 1, A=inn, B=ut c6/c7=ut */ outportb(DATA_B,0x66); /* Trekk OBF port B lavt */ j = inportb(DATA_A); /* Trekk IBF port A lavt */ /* Aktiviser 8255A for avbrudd */ outportb(KNTR8255,0x09); /* Sett INTE A (c4) */ outportb(KNTR8255,0x05); /* Sett INTE B (c2) */ }