/***************************************************************************** * This is the root module for the IOD boards demonstration for * * interrupt programming. * *****************************************************************************/ #include #include #include #include #include #include #include #define IRQ 5 /* these are the port address offsets for reading and control of the IOD */ unsigned int PortA; unsigned int PortB; unsigned int PortC; unsigned int PortControl; /* this typedef allow use to duplicate the boolean type as used in pascal */ typedef enum {FALSE,TRUE} boolean; unsigned int isr_flag; /* used to indicate an interrupt occurred */ /***************************************************************************** * FUNCTION: IOD_write_port -- export routine * * PURPOSE: Writes the value contained at one of the 3 ports contained on * * the IOD board. * *****************************************************************************/ void IOD_write_port(unsigned port,unsigned char value) { outportb(port,value); } /* end IOD_write_port */ /***************************************************************************** * FUNCTION: IOD_read_port -- export routine * * PURPOSE: Reads the value contained at one of the 6 ports contained on * * the IOD board. * *****************************************************************************/ char IOD_read_port(unsigned port) { char value; value = inportb(port); return(value); } /* end IOD_read_port */ /***************************************************************************** * FUNCTION: IOD_port_control -- export routine * * PURPOSE: Writes the control word to IOD digital board. This word * * determines the direction of digital I/O as well mode. * * See IOD manual for more information. * *****************************************************************************/ void IOD_port_control(unsigned port,char value) { outportb(port,value); /* send the byte */ } /* end IOD_port_control */ /***************************************************************************** * FUNCTION: signon -- local routine * * PURPOSE: To display an initial sign on message on the screen. * *****************************************************************************/ void signon(void) { #define L1 " I O D I N T E R R U P T D E M O N S T R A T O R " #define L4 " BIT STATUS " #define L5 " --- ------ " #define L6 " PRESS ANY KEY TO EXIT PROGRAM " int index; /* print the string display */ clrscr(); gotoxy(10,1); printf("%s",L1); gotoxy(30,6); printf("%s",L4); gotoxy(30,7); printf("%s",L5); gotoxy(21,25); printf("%s",L6); for (index = 0;index < 16;index++) /* print the bit field labels */ { gotoxy(31,index + 8); printf("%2d",index); } } /* end signon */ /***************************************************************************** * FUNCTION: write_port_data -- local routine * * PURPOSE: Displays the current port values on the screen. * *****************************************************************************/ void write_port_data(unsigned current[3]) { unsigned x,y,index1,index,value; x = 40; /* x coordinate to write value to screen */ y = 8; for (index = 0;index <= 1;index++) /* for each array member */ { value = current[index]; for (index1 = 0;index1 <= 7;index1++) /* for each bit in array member */ { gotoxy(x,y); if (value % 2) putchar('1'); else putchar('0'); value = value >> 1; /* roll next diaplay bit */ y++; } } } /* end write_port_data */ /***************************************************************************** * FUNCTION: setflag -- global routine * * PURPOSE: This is The interrupt service routine. It is called when the * * IOD board has detected a user interrupt on port C bit 3. * *****************************************************************************/ void interrupt setflag(void) { disable(); /* do not allow further interrupts */ isr_flag = 1; /* indicate an interrupt has occurred */ outportb(0x20,0x20); /* clear interrupt and allow next one */ enable(); } /* end setflag */ /***************************************************************************** * FUNCTION: read_IOD_ports - local routine * * PURPOSE: Reads first 3 IOD ports. * *****************************************************************************/ void read_IOD_ports(unsigned current[3]) { current[0] = IOD_read_port(PortA); current[1] = IOD_read_port(PortB); current[2] = IOD_read_port(PortC); } /* end read_IOD_ports */ /****************************************************************************** Function AskForBaseAddress Purpose: This function allows the user to input the address of the card. *****************************************************************************/ unsigned AskForBaseAddress(unsigned int OldOne) { char msg[7]; int NewOne = 0, Success = 0, Dummy; int AddrInputPosX, AddrInputPosY; puts("\nPlease enter the Base Address for your card (in hex)"); printf("or press ENTER for %X.\n>", OldOne); AddrInputPosX = wherex(); AddrInputPosY = wherey(); do { gotoxy(AddrInputPosX, AddrInputPosY); clreol(); msg[0] = 5; msg[1] = 0; cgets(msg); sscanf(msg + 2, "%x", &NewOne); Success = 1; Dummy = NewOne; if (msg[1] == 0) { gotoxy(AddrInputPosX, AddrInputPosY); printf("%X", OldOne); Success = 1; Dummy = OldOne; } } while(!Success); return (Dummy); } /* end of AskForBaseAddress */ /***************************************************************************** * FUNCTION: main -- external routine * * PURPOSE: To perform the program control functions. * *****************************************************************************/ void main() { int int_mask; void (interrupt far *oldisr)(); unsigned current[3]; clrscr(); puts(" SAMPLE 2.C : Interrupt Programming"); puts(""); puts("This program is an example of interrupt programming for the IOD96M."); gotoxy(1,5); PortA = AskForBaseAddress(0x2A0); PortB = PortA + 1; PortC = PortA + 2; PortControl = PortA + 3; clrscr(); printf("\n\n\nBoard Configuration:\n\n"); printf(" -- Base Addresss is %X hex.\n",PortA); printf(" -- The IRQ5 jumper should be installed (required)\n"); printf(" -- All other jumper settings are irrelevant.\n\n\n"); printf("Press a key to continue."); getch(); disable(); /* do not allow hardware interrupts */ signon(); /* print the start up message */ isr_flag = 0; oldisr = getvect(0x0d); /* save old IRQ5 interrupt vector */ setvect(0x0d,setflag); /* set IRQ5 to our interrupt routine */ int_mask = inportb(0x21); /* get hardware interrupt mask */ int_mask = int_mask &~(1<