/* demo 4 : INT_CHAN_3, timer interrupt, demo */ /* (it is designed to be a machine independent timer) */ /* step 1 : run demo4.exe */ /* ----------------------------------------------------------- */ #include "PIO.H" #define A1_8259 0x20 #define A2_8259 0xA0 #define EOI 0x20 WORD init_high(); WORD wBase,wIrq; WORD pio_d48_c0(char cConfig, char cLow, char cHigh); WORD pio_d48_c1(char cConfig, char cLow, char cHigh); WORD pio_d48_c2(char cConfig, char cLow, char cHigh); static void interrupt irq_service(); static int COUNT,now_int_state,irqmask; int main() { int i,j; WORD wBoards,wRetVal; WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice,t1,t2,t3,t4,t5; char c; DWORD dwVal; /* step 1: find address-mapping of PIO/PISO cards */ clrscr(); wRetVal=PIO_DriverInit(&wBoards,0x80,0x01,0x30); /* for PIO-D48 */ printf("\nThrer are %d PIO_D48 Cards in this PC",wBoards); if (wBoards==0) exit(0); printf("\n----------------- The Configuration Space -------------------------"); for(i=0; i "); ShowPioPiso(wSubVendor,wSubDevice,wSubAux); } /* select card_0 */ PIO_GetConfigAddressSpace(0,&wBase,&wIrq,&t1,&t2,&t3,&t4,&t5); /* step 2: enable all D/I/O port */ outportb(wBase,1); /* enable D/I/O */ init_high(); /* interrupt initialize, INIT_CHAN_3 is HIGH now */ COUNT=0; printf("\n*** show the count of Low_pulse ***\n"); for (;;) { printf("\nLow Pulse Count=%d (one low pulse every second) INT_STATUS=[%x %x]",COUNT, inportb(wBase+7)&8, now_int_state); if (kbhit()!=0) {getch(); break;} } outportb(wBase+5,0); /* disable all interrupt */ PIO_DriverClose(); } /* -------------------------------------------------------------------- */ /* Use INT_CHAN_3 as external interrupt signal */ WORD init_high() { DWORD dwVal; disable(); outportb(wBase+5,0); /* disable all interrupt */ if (wIrq<8) { irqmask=inportb(A1_8259+1); outportb(A1_8259+1,irqmask & (0xff ^ (1 << wIrq))); setvect(wIrq+8, irq_service); } else { irqmask=inportb(A1_8259+1); outportb(A1_8259+1,irqmask & 0xfb); /* IRQ2 */ outportb(A1_8259+1,irqmask & (0xff ^ (1 << wIrq))); irqmask=inportb(A2_8259+1); outportb(A2_8259+1,irqmask & (0xff ^ (1 << (wIrq-8)))); setvect(wIrq-8+0x70, irq_service); } /* select CLK1=32768 Hz */ outportb(wBase+0xf0,0x15); /* CTRL_D0=1-->timer clock=32768 Hz */ /* program OUT1 to 2 Hz */ pio_d48_c1(0x76,0,0x40); /* COUNTER1,MODE-3,32768/0x4000=2 Hz */ /* program OUT2 to 1 Hz */ /* note: the 8254 need extra 2-clock for initialization */ pio_d48_c2(0xb6,2,0); /* COUNTER2,MODE-3,2/2=1Hz */ for (;;) /* wait COUT2=HIGH */ { if ((inportb(wBase+7)&8)!=0) break; } /* Note: now the COUT2 is HIGH */ /* --> INV3 must select the inverted COUT2 */ /* --> INT_CHAN_3=!COUT2=init_LOW, active_HIGH */ outportb(wBase+0x2a,0); /* select the inverted COUT2 */ /* INT_CHAN_3=!COUT2 */ now_int_state=1; /* now COUT2 is high */ outportb(wBase+5,8); /* enable INT_CHAN_3 interrupt */ enable(); } /* -------------------------------------------------------------------- */ void interrupt irq_service() { if (now_int_state==1) /* now COUT2 is changed to LOW */ { /* --> INT_CHAN_3=!COUT2=HIGH now */ COUNT++; /* find a LOW_pulse (COUT2) */ if((inportb(wBase+7)&8)==0) /* the COUT2 is still fixed in LOW */ { /* --> need to generate a high_pulse */ outportb(wBase+0x2a,8); /* INV3 select the non-inverted input */ /* INT_CHAN_3=COUT2=LOW --> */ /* INT_CHAN_3 generate a high_pulse */ now_int_state=0; /* now COUT2=LOW */ } else now_int_state=1; /* now COUT2=HIGH */ /* (no need to generate high_pulse ) */ } else /* now COUT2 is changed to HIGH */ { /* --> INT_CHAN_3=COUT2=HIGH now */ /* find a HIGH_pulse (COUT2) */ if((inportb(wBase+7)&8)==8) /* the COUT2 is still fixed in HIGH */ { /* --> need to generate a high_pulse */ outportb(wBase+0x2a,0); /* INV3 select the inverted input */ /* INT_CHAN_3=!COUT2=LOW --> */ /* INT_CHAN_3 generate a high_pulse */ now_int_state=1; /* now COUT2=HIGH */ } else now_int_state=0; /* now COUT2=LOW */ /* (no need to generate high_pulse ) */ } if (wIrq>=8) outportb(A2_8259,0x20); outportb(A1_8259,0x20); } /* -------------------------------------------------------------------- */ WORD pio_d48_c0(char cConfig, char cLow, char cHigh) /* COUNTER_0 */ { outportb(wBase+0xec,cConfig); outportb(wBase+0xe0,cLow); outportb(wBase+0xe0,cHigh); return(NoError); } WORD pio_d48_c1(char cConfig, char cLow, char cHigh) /* COUNTER_1 */ { outportb(wBase+0xec,cConfig); outportb(wBase+0xe4,cLow); outportb(wBase+0xe4,cHigh); return(NoError); } WORD pio_d48_c2(char cConfig, char cLow, char cHigh) /* COUNTER_2 */ { outportb(wBase+0xec,cConfig); outportb(wBase+0xe8,cLow); outportb(wBase+0xe8,cHigh); return(NoError); }