The serial port enables to the electronic designer to communicate a PC with devices that supports the RS-232 standard. On the other hand, the parallel port outputs eight data bits and five input signals. It outputs only one interrupt signal (IRQ7).
On the contrary the ISA BUS outputs a 20 bit address bus and a 8 bit data BUS. Allows to manage most of the PC interrupt signals and even, drive DMA (direct memory access) transfers.
In the figure you can see the pinouts of the ISA BUS. The BUS is divided into two sides. The first side pins are named A1 to A31 and it is the components side. It consist of the address and data buses. The second side pins are named B1 to B31 and it is the solder side. This side contents the power pins and the signals related to interrupts and DMA transfers.
We list the most used pins and its description below. For the "A" side:
A0-A19 (pins A31 to A12): This twenty lines are the address BUS. They can address 1MB (2^20 bytes).
D0-D7 (pins A9 to A2): The data BUS consist of this eight data lines.
AEN (pin B11): It is used for the DMA controller to take over the data and address buses in a DMA transfer.
For the "B" side:
GND (pins B1, B10, B31): Connected to the ground of the computerLet's start describing the operation of the ISA bus with a simple read cycle from an Input/Output port. The first thing the microprocessor does is to send out a high on the ALE signal, then sends out the A0-A19 lines. After, the ALE signal goes low. From now on the address of the target port to be read will be latched. Then the BUS takes the -IOR signal to a low level. So that the addressed device will take a data byte to the D0-D7 data bus. The microprocessor will read then the data bus and take the -IOR signal to a high again.
A write cycle to a port works this way: The microprocessor asserts the ALE high, then outputs A0-A19. ALE goes low again. The microprocessor send out the data byte to be write. It then asserts the -IOW signal. After the device have time to read the data byte, the uP raises the -IOW signal high again.
The only difference between a memory read/write cycle and a port read/write cycle is that in a memory cycle the -MEMR and -MEMW signals will be asserted, working the same way as -IOR and -IOW do.
In the PC memory map we can find two kinds of interrupts, the software interrupts and the hardware interrupts. In this tutorial only the hardware interrupts will be explained. In a PC, the external interrupts are driven by the 8259A priority interrupt controller. When an 8259A receives an interrupt signal through the IRQ2 to IRQ7 signals, it sends an interrupt request signal to the INTR input of the uP. Then the 8086 outputs an INTA (interrupt-acknowledge) signal to the 8259. So that the uP can get interrupt type of the external device. The 8086 then uses the type read from the external device to get the address for the interrupt-service procedure from the interrupt pointer table in memory. Note that INTR and INTA are not present in the ISA bus, this signals are only used for the uP and the 8259A.
The basic target of an interrupt is to execute a function that response to the request of a hardware device. An interrupt vector contents the address of this function. In an 8086 system the first Kbyte of memory (from 00000H to 003FFH) is used for the interrupt vectors. To point to any address of the whole memory map four bytes are needed. 16 bits for the base address and 16 bits to identify the segment. So, a 1Kbyte of memory allows to store 256 interrupt vectors. Some of the 256 interrupt vectors are used for the system, others are free to be used for the user programs. To install a user interrupt service procedure you can use a program like the one of the example.
The program install an interrupt routine in the IRQ1 interrupt channel, which is the system timer.
This timer generates an interrupt 18.2 times per second. In the interrupt service routine,
we increment a global variable. When this variable equals to 18 is printed on the screen.
So that, we will get on the screen a second counter.
|
#include <dos.h> #include <stdio.h> #include <conio.h> #include <bios.h> #define IMR 0x21 int _key=1; int global=0; void interrupt (*_old_int_function)(); char _old_mask; char _interrupt_mask(int IRQn) { char p=1; p=p< } void _install_int_function(int IRQn, void interrupt (*_new_int_function)()) { int inter = IRQn + 8; _disable(); //disable interrupts _old_int_function=_dos_getvect(inter); //save the old interrupt vector _dos_setvect(inter,_new_int_function); //install the new interrupt vector _old_mask=inportb(IMR); //save the state of the 8259A IMR register outportb(IMR,_old_mask&_interrupt_mask(IRQn)); //Set new value for IMR register _enable(); //enable interrupts } void _end_interrupt(void) { outportb(0x20,0x20); } void _Unistall_new_int_function(int IRQn) { int inter = IRQn + 8; _disable(); //disable interrupts _dos_setvect(inter,_old_int_function); //restore the old interrupt service function outportb(IMR,_old_mask); //restore the IMR _enable(); //enable interrupts again } void interrupt _new_int_function() { _disable(); //disable interrupts global++; //global count the number of interrupts //that the system has requested _end_interrupt(); //to tell the system the interrupt service function has finished _enable(); //enable interrupts again } /*********************************************************/ /*Read the keyboard. If "ESC" is pressed the program ends*/ /*********************************************************/ void _keyboard(void) { union u_type{int a;char b[3];}keystroke;char inkey=0; if(bioskey(1)==0) return; keystroke.a=bioskey(0); inkey=keystroke.b[1]; switch (inkey) { case 1: _key=0; return; case 11: _key=39; return; /*_key 0*/ default: _key=15; return; } } void main(void) { int second=0; clrscr(); cprintf("Press 'ESC' to exit \n \n"); _install_int_function(0,_new_int_function); do { _keyboard(); //read the keyboard if (global >=18) { second++; //incremented each second gotoxy(2,2); cprintf("Time: %d",second); global=0; } } while(_key !=0); _Unistall_new_int_function(0); } |
Some input/output devices send data faster than the microprocessor can get it. The DMA (Direct Memory Access) is a dedicated IC that sends and receives data faster than the microprocessor. So magnetic and optical disks use this IC to access the memory of the system.
The DMA (Direct Memory Access) controller borrows the address bus, the data bus and the control bus from the system and transfers a programmed series of bytes from a fast I/O device to the memory. The 8237 DMA controller is the device used for the PC to do this job.
When a device has a data block ready to be send to the memory, sends a DMA request asserting a DRQn signal to the DMA controller. If the requested channel is unmasked, the DMA will send a HRQ (hold request) signal to the microprocessor. The microprocessor will respond floating its buses and sending a HLDA (hold acknowledge) signal to the DMA. Then the DMA gets the control of the buses asserting the AEN signal high and sending out the address of memory to be written. Next the DMA outputs the DACKn (DMA acknowledge) to the device. Finally the DMA controller asserts the MEMW and IOR signals on the control bus. When the data transfer is completed unasserts the HRQ signal and the processor gets the control of the buses again.
If a device needs some data from the memory, the process is similar. The only difference is that the DMA controller outputs the MEMR and IOW on the control bus.
Please e-mail us at: pckits@apdo.com