/* * (C) 1984 UniSoft Corp. of Berkeley CA * * UniPlus Source Code. This program is proprietary * with Unisoft Corporation and is not to be reproduced * or used in any manner except as authorized in * writing by Unisoft. * * Interrupt handler for level 2 interrupts. *	keyboard, mouse, real time clock, on/off switch */#include "sys/param.h"#include "sys/types.h"#include "sys/mmu.h"#include "sys/reg.h"#include "sys/local.h"#include "sys/cops.h"#include "sys/keyboard.h"#include "sys/mouse.h"#include "sys/ms.h"#include "sys/l2.h"#include "sys/kb.h"extern struct rtime rtime;char *kb_keytab = ToLA;char kb_altkp;			/* are we in alternate keypad mode? (set in vt100.c) */char pportplug;char ms_plg, ms_btn;short ms_row, ms_col;kbintr(){	register char i;	register struct device_e *p = COPSADDR;	register char a, ud;	register int tmp;	extern time_t lbolt;#ifdef SUNIX	extern char kb_getchr;	/* flag for polling keyboard */#endif SUNIX	a = p->e_ifr;			/* Read and save reason for interrupt */	if (a & FCA1) {			/* keyboard input */		i = p->e_ira;			/* get keyboard/mouse input */		if (a & FTIMER1)			a = COPSADDR->e_t1cl;	/* prime timer */	} else {			/* no character input */		a = COPSADDR->e_t1cl;		/* prime timer */		if (--kb_reptrap == 0)			kbrepeat();		/* possible char repeat */		return;			}	switch (kb_state) {	case NORMALWAIT:		/* IDLE LOOP */		ud = i & 0x80;		/* whether up or down keycode */		l2_dtrap = lbolt + l2_dtime;	/* reset dim delay */		if (l2_dimmed)		/* restore screen intensity */			l2undim();		a = kb_keytab[i & 0x7F];/* convert to ascii */		if (ud) {		/* "key went down" bit *//* click(); /* key click */			if (ARROW(i,a)) {	/* check arrow keys */				kb_chrbuf = Esc;    /* send 3-char sequence */				cointr(0);				kb_chrbuf = '[';				cointr(0);				kb_chrbuf = a;				cointr(0);				goto out;			}			if (kb_altkp) {	/* send special sequence for keypad chars */				if (a = altkpad[i & 0x7F]) {/* is it in the keypad? */					kb_chrbuf = Esc;    /* send 3-char sequence */					cointr(0);					kb_chrbuf = 'O';					cointr(0);					kb_chrbuf = a;					cointr(0);					goto out;				}				a = kb_keytab[i & 0x7F];/* reset to ascii */			}			if (a >= 0) {	/* ascii ? */				kb_keycount++;				if (kb_ctrl) a &= 0x1F;				else if (kb_keycount == 1) {					kb_reptrap = kb_repwait;					kb_lastc = a;				} else kb_reptrap = 0;				kb_chrbuf = a;				cointr(0);				goto out;			}		} else {		/* key went up */			kb_reptrap = 0;			if (a >= 0) {				if (kb_keycount-- < 0) {					kb_keycount = 0;				}				goto out;			}		}		switch (a & 0xF) {		case KB_CTRL:	kb_ctrl = ud; kb_reptrap = 0; msintr(M_CTL);								goto out;		case KB_SHFT:	kb_shft = ud; kbsetcvtab(); msintr(M_SFT);								goto out;		case KB_LOCK:	kb_lock = ud; kbsetcvtab();	goto out;		case KB_OFF:	printf("[SOFT OFF %x]\n",i);	goto out;		case KB_MSP:	ms_plg = ud; msintr(M_PLUG);	goto out;		case KB_MSB:	ms_btn = ud; msintr(M_BUT);	goto out;		case KB_PPORT:	pportplug = ud;			goto out;		case KB_D2B:	printf("[disk1button %x]\n",i);	goto out;		case KB_D2P:	printf("[disk1 %x]\n",i);	goto out;		case KB_D1B:	printf("[disk2button %x]\n",i);	goto out;		case KB_D1P:	printf("[disk2 %x]\n",i);	goto out;		case KB_STATE:	if (ud == 0) {					kb_state = MOUSERD;				} else					kb_state = RESETCODE;				goto out;		default:	printf("invalid key[0x%x]",i);		}		goto out;	case MOUSERD:		/* PICKUP Y axis change in mouse pos */		kb_state = YMOUSE;		ms_col = (short)i;		goto out;	case YMOUSE:		/* PICKUP Y axis change in mouse pos */		kb_state = NORMALWAIT;		ms_row = (short)i;		msintr(M_MOVE);		goto out;	case RESETCODE:		/* special condition */		switch (i & 0xFF) {		case KB_KBCOPS:	/* keyboard cops failure detected */			printf("KEYBOARD COPS FAILURE\n");			break;		case KB_IOCOPS:	/* IO board cops failure detected */			printf("IO BOARD COPS FAILURE\n");			break;		case KB_UNPLUG:	/* keyboard unplugged */			kb_chrbuf = 's'&0x1F;	/* cntl S */			cointr(0);			break;		case KB_CLOCKT:	/* clock timer interrupt */			printf("Real Time Clock interrupt\n");			break;		case KB_SFTOFF:	/* soft power switch */			kb_state = SHUTDOWN;			printf("Shutting down...\n");			update();			for (tmp = 0; tmp < 500000; tmp++);			l2_crate = 2;			l2_desired = TOTALDIM;	/* completely blacken screen */			l2ramp(0);			l2ramp(0);			SPL7();			/* extreme priority */			l2copscmd(SHUTOFF);			rom_mon();		/* return to the ROM monitor */			/*NOTREACHED*/		default: switch (i & 0xF0) {			case KB_RESERV:				printf("[Reserved keycode 0x%x]\n",i);				break;			case KB_RDCLK:				rtime.rt_year = (i & 0xF) + 10;					kb_state = CLKREAD;				goto out;			default:				kb_idcode = i;				kb_chrbuf = 'q'&0x1F;	/* cntl Q */				cointr(0);				printf("Keyboard type 0x%x\n",i);			}		}		kb_state = NORMALWAIT;		goto out;	case CLKREAD:		rtime.rt_day = (((i&0xF0)>>4)*10 + (i&0xF))*10;		kb_state++;		goto out;	case CLKREAD+1:		rtime.rt_day += (i&0xF0) >> 4;		rtime.rt_hour = (i & 0xF) * 10;		kb_state++;		goto out;	case CLKREAD+2:		rtime.rt_hour += (i & 0xF0) >> 4;		rtime.rt_min = (i & 0x0F) * 10;		kb_state++;		goto out;	case CLKREAD+3:		rtime.rt_min += (i & 0xF0) >> 4;		rtime.rt_sec = (i & 0x0F) * 10;		kb_state++;		goto out;	case CLKREAD+4:		rtime.rt_sec += (i & 0xF0) >> 4;		rtime.rt_tenth = i & 0x0F;		kb_state = NORMALWAIT;		rtcsettod();		goto out;	case SHUTDOWN:		goto out;	}out:	;#ifdef SUNIX	if (!ud)		kb_getchr = 0;#endif SUNIX}kbrepeat (){	kb_reptrap = kb_repdlay;		/* reset repeat timeout */	if (kb_keycount == 1) {		kb_chrbuf = kb_lastc;/* click(); /* key click */		cointr(0);	} else		kb_reptrap = 0;		/* reset repeat timeout */}kbsetcvtab(){	kb_keytab = ccvtab[(kb_shft?2:0)+(kb_lock?1:0)];	kb_reptrap = 0;}