Specifications

70 Chapter 5 - Software Interface
union REGS regs;
regs.x.ax = 0xc400;
int86(0x15,&regs,&regs);
posbase = regs.x.dx;
for (i=1; i<9; i++) { /* check each slot for 2202 controller */
regs.x.ax = 0xc401;
regs.h.bl = i;
int86(0x15,&regs,&regs);
for (j=0; j<8; j++) /* read ID and POS registers */
mcainfo[j] = (byte)inp(posbase+j);
regs.x.ax = 0xc402;
regs.h.bl = i;
int86(0x15,&regs,&regs);
if (((mcainfo[0] + ((unsigned)mcainfo[1] << 8)) == IBM_ID) && /* check ID */
((mcainfo[6] + ((unsigned)mcainfo[7] << 8)) == ~IBM_ID)) {
baseport = mcainfo[3] + ((unsigned)mcainfo[4] << 8);
/* intrpt = mcainfo[5] & 0xf; */
return(OK);
}
}
return(NOCONTROLLER);
}
void resetmcacontrollerpos(void)
/* disable controller so it can be detected again through POS registers */
{
static packettype quiet = {'Q',1,0,0,0,0,0,0};
sendpacket(quiet); /* no acknowledge on Quiet all command */
}
Interrupt-Driven Code
Interrupt-driven code is hardware and operating system dependent, and is
therefore beyond the scope of this manual. To simplify the code required, you may
use the polled code in the previous examples to locate and set up the controller,
then operate with one-way communication only. The interrupt service routine then
only has to accept Touch packets.
For more information on bus controller interrupts, see Interrupt Mode, page 56.