Interrupts Using the MFP January 11, 1994 $Source: /u/cyliax/Projects/030/Doc/Prog/mfpint.ms,v $ The MFP is a versatile device. It has 4 timers, an 8bit parallel port and a USART. In our workstation, the input section of the USART is used for the keyboard and one of the timers (timer D) is used to drive the speaker. 6 of the 8bit parallel port are used to sense interrupts on the 16bit ISA bus and and 2 to program the keyboard. All the different interrupt sources are combined to generate a single level 6 autovectorred interrupt (offset 78h in vector table). The interrupt mask registers (a and b) mask which of the 16 sources on the chip cause an external interrupt. A zero will mask the interrupt and a 1 will enable it. The interrupt pending registers (a and b) are used to determine which internal source actually generated the interrupt and to clear the interrupt by setting the corresponding bit to zero. Here is a table of all the MFP internal sources and what they are mapped to on the workstation. priority bit source function 15 7(a) gpip7 16bit ISA-bus 14 6(a) gpip6 " 13 5(a) Timer A 60hz clock 12 4(a) RCV full kbd receive 11 3(a) RCV error kbd error 10 2(a) XMIT empty not used 9 1(a) XMIT error not used 8 0(a) Timer B not used 7 7(b) gpip5 16bit ISA-bus 6 6(b) gpip4 " 5 5(b) Timer C not used 4 4(b) Timer D speaker 3 3(b) gpip3 16bit ISA-bus 2 2(b) gpip2 " 1 1(b) gpip1 kbd data 0 0(b) gpip0 kbd clock To service a mfp interrupt, both interrupt pending registers should be examined to determine the source of the interrupt. Once the source has been located and the appropriate function is performed in the interrupt handler, the corresponding bit in the interrupt pending register is cleared. Minix will initialize Timer A to interrupt at a rate of 60hz (60 times a second). Minix also enables the receive buffer full interrupt from the USART. Here is a typical interrupt handler that would be used to service the 60hz January 11, 1994 - 2 - timer and USART interrupt. start: move.l vbr,a0 move.l #lvl6,$78(a0) * set the interrupt vector idle: stop $2000 * wait for interrupt bra idle * tick: dc.l 0 * mfpipra equ $7f200005 * interrupt pending register A mfpiprb equ $7f200006 * " " " B timera equ 5 * bit for timera interrupt rcvful equ 4 * bit for usart receive buffer full lvl6: btst.b #timera,mfpipra * timer A ? beq l6_1 * nope add.l tick * increment the tick counter * add some other code here... l6_1: btst.b #rcvful,mdpipra * kbd buffer full ? beq l6_done * nope * read keyboard here for example l6_done: clr.b mfpipra * all done, clear pending interrupts clr.b mfpiprb rte January 11, 1994