Listing 3 (char.c) Main Interrupt Routine; also Keyboard Read Routine
#include "char.h" /*-------- Prototypes ---------*/ /* handle init call */ extern void char_init (void); /* look up key code for reassignment */ extern char *k_seek (void); /* read the keyboard */ extern void rawread (void); /* see if char is available at the keyboard */ extern int rawstat (void); /* write byte into ring buffer */ extern void r_write (char); /* write character to screen */ extern void w_putc (void); /* * rd_getc() * * rd_getc() reads a character from the keyboard, hanging until * there is one. If the character has been reassigned, copy the * reassignment buffer into the ring buffer. Otherwise, write * the character itself (with leading nul byte for extended * keys) into the ring buffer */ void rd_getc() { if (r_index == w_index) { rawread(); if (k_seek()) { for (k = 0; k <*len; k++) r_write(*ptr++); } else { if (keycheck & 0177400) r_write(0); r_write(((char) keycheck) & 0000377); } } } /* * interrupt() * * interrupt() takes care of the commands as they come in from * the request header. Of all the commands, only the device * initialization call is a separate function; this reduces * stack overhead. char_init() is a separate function, alone in * its own module, so that it can report its own address as the * end of the driver. */ void interrupt() { count = rh->count; transfer = rh->transfer; switch (rh->command) { case 0: /* initialization */ char_init(); break; case 4: /* read */ while (count) { rd_getc(); *transfer++ = r_buf[ r_index++ ] & 000377; r_index &= RLIMIT; count--; } rh->status = DONE; break; case 5: /* non-destr uctive read */ if (r_index == w_index) { if (!rawstat()) { rh->status = BUSY | DONE; break; } rd_getc(); } rh->status = DONE; rh->data = r_buf[ r_index ]; break; case 7: /* flush input buffers */ r_index = w_index = 0; while (rawstat()) rawread(); rh->status = DONE; break; case 8: /* write */ case 9: /* write with verify */ while (count) { outchar = *transfer++; w_putc(); count--; } case 1: /* media check */ case 2: /* build parameter block */ case 6: /* input status */ case 10: /* output status */ case 11: /* flush output buffers */ rh->status = DONE; break; case 3: /* ioctl read */ default: rh->status = UNKNOWN_COMMAND | ERROR | DONE; break; } }