|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 9272 (0x2438) Types: TextFile Notes: UNIX file Names: »kev.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦2d53db1df⟧ UNIX Filesystem └─ ⟦this⟧ »hr/src/smgr/kev.c«
#include <stdio.h> #include <errno.h> #include <smgr.h> /* * Keyboard/display driver. */ #define SPC 0376 /* Special encoding */ #define XXX 0377 /* Non-character */ #define KBDATA 0x60 /* Keyboard data */ #define KBCTRL 0x61 /* Keyboard control */ #define KBFLAG 0x80 /* Keyboard reset flag */ #define KEYUP 0x80 /* Key up change */ #define KEYSC 0x7F /* Key scan code mask */ #define LSHIFT 0x2A-1 /* Left shift key */ #define LSHIFTA 0x2B-1 /* Alternate left-shift key */ #define RSHIFT 0x36-1 /* Right shift key */ #define CTRL 0x1D-1 /* Control key */ #define ALT 0x38-1 /* Alt key */ #define CAPLOCK 0x3A-1 /* Caps lock key */ #define DELETE 0x53-1 /* Del, as in CTRL-ALT-DEL */ #define BACKSP 0x0E-1 /* Back space */ #define SCRLOCK 0x46-1 /* Scroll lock */ /* Shift flags */ #define SRS 0x01 /* Right shift key on */ #define SLS 0x02 /* Left shift key on */ #define CTS 0x04 /* Ctrl key on */ #define ALS 0x08 /* Alt key on */ #define CPLS 0x10 /* Caps lock on */ #define NMLS 0x20 /* Num lock on */ #define AKPS 0x40 /* Alternate keypad shift */ #define SHFT 0x80 /* Shift key flag */ /* Function key information */ #define NFKEY 40 /* Number of settable functions */ #define NFCHAR 600 /* Number of characters settable */ #define NFBUF (NFKEY*2+NFCHAR+1) /* Size of buffer */ /* ASCII codes */ #define DEL 0x7f /* delete code */ /* * State variables. */ static char shift; /* Overall shift state */ static char lshift = LSHIFT; /* Left shift alternate state */ static int kbd_wid; extern int myfd; extern POINT SM_Mouse_Pos; /* * Tables for converting key code to ASCII. * lmaptab specifies unshifted conversion, * umaptab specifies shifted conversion, * smaptab specifies the shift states which are active. * An entry of XXX says the key is dead. * An entry of SPC requires further processing. * * Key codes: * ESC .. <- == 1 .. 14 * -> .. \n == 15 .. 28 * CTRL .. ` == 29 .. 41 * ^Shift .. PrtSc == 42 .. 55 * ALT .. CapsLock == 56 .. 58 * F1 .. F10 == 59 .. 68 * NumLock .. Del == 69 .. 83 */ static unsigned char lmaptab[] ={ '\33', '1', '2', '3', '4', '5', '6', /* 1 - 7 */ '7', '8', '9', '0', '-', '=', '\b', '\t', /* 8 - 15 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* 16 - 23 */ 'o', 'p', '[', ']', '\r', XXX, 'a', 's', /* 24 - 31 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 32 - 39 */ '\'', '`', XXX, '\\', 'z', 'x', 'c', 'v', /* 40 - 47 */ 'b', 'n', 'm', ',', '.', '/', XXX, SPC, /* 48 - 55 */ XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */ SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */ SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */ SPC, SPC, SPC, SPC, SPC, DEL, SPC, SPC, /* 80 - 87 */ SPC, SPC, SPC, SPC, SPC, SPC, '\r', SPC, /* 88 - 95 */ SPC, SPC, SPC, XXX, XXX /* 96 - 100*/ }; static unsigned char umaptab[] ={ '\33', '!', '@', '#', '$', '%', '^', /* 1 - 7 */ '&', '*', '(', ')', '_', '+', '\b', '\t', /* 8 - 15 */ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* 16 - 23 */ 'O', 'P', '{', '}', '\r', XXX, 'A', 'S', /* 24 - 31 */ 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 32 - 39 */ '"', '~', XXX, '|', 'Z', 'X', 'C', 'V', /* 40 - 47 */ 'B', 'N', 'M', '<', '>', '?', XXX, SPC, /* 48 - 55 */ XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */ SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */ SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */ SPC, SPC, SPC, SPC, SPC, DEL, SPC, SPC, /* 80 - 87 */ SPC, SPC, SPC, SPC, SPC, SPC, '\r', SPC, /* 88 - 95 */ SPC, SPC, SPC, XXX, XXX /* 96 - 100*/ }; #define SS0 0 /* No shift */ #define SS1 (SLS|SRS|CTS) /* Shift, Ctrl */ #define SES (SLS|SRS) /* Shift */ #define LET (SLS|SRS|CPLS|CTS) /* Shift, Caps, Ctrl */ #define KEY (SLS|SRS|NMLS|AKPS) /* Shift, Num, Alt keypad */ static unsigned char smaptab[] ={ SS0, SES, SS1, SES, SES, SES, SS1, /* 1 - 7 */ SES, SES, SES, SES, SS1, SES, SS0, SS0, /* 8 - 15 */ LET, LET, LET, LET, LET, LET, LET, LET, /* 16 - 23 */ LET, LET, SS1, SS1, SS0, SHFT, LET, LET, /* 24 - 31 */ LET, LET, LET, LET, LET, LET, LET, SES, /* 32 - 39 */ SES, SS1, SHFT, SS1, LET, LET, LET, LET, /* 40 - 47 */ LET, LET, LET, SES, SES, SES, SHFT, SS0, /* 48 - 55 */ SHFT, SS1, SHFT, SS0, SS0, SS0, SS0, SS0, /* 56 - 63 */ SS0, SS0, SS0, SS0, SS0, SS0, KEY, KEY, /* 64 - 71 */ KEY, KEY, SS0, KEY, KEY, KEY, SS0, KEY, /* 72 - 79 */ KEY, KEY, KEY, KEY, SS0, SS0, SS0, SS0, /* 80 - 87 */ SS0, SS0, SS0, SS0, SS0, SS0, SS0, SS0, /* 88 - 95 */ SS0, SS0, SS0, LET, LET /* 96 - 100*/ }; /* ** When the keyboard interrupt routine sends a key position to ** the screen manager sm_key routine is called. This routine checks ** the key position to decide if the key was for screen manager or ** or for an active window and then calls an appropriate routine ** to do the work. */ SM_Keyboard() { register int c; register int s; register int r; r = msgData1 & 0xFF; if (r == 0xFF) return; /* Overrun */ c = (r & KEYSC) - 1; #ifdef DEBUG if ( ~(r&KEYUP) ) printf("KEY:\t0x%x %d\n", r, r); #endif /* * Track "shift" keys. */ s = smaptab[c]; if (s&SHFT) { if (r&KEYUP) { /* "shift" released */ if (c == RSHIFT) shift &= ~SRS; else if (c == lshift) shift &= ~SLS; else if (c == CTRL) shift &= ~CTS; else if (c == ALT) shift &= ~ALS; } else { /* "shift" pressed */ if (c == lshift) shift |= SLS; else if (c == RSHIFT) shift |= SRS; else if (c == CTRL) shift |= CTS; else if (c == ALT) shift |= ALS; else if (c == CAPLOCK) shift ^= CPLS; /* toggle cap lock */ #ifdef NUMLOCK else if (c == NUMLOCK) shift ^= NMLS; /* toggle num lock */ #endif } return; } /* * No other key up codes of interest. */ if (r&KEYUP) return; /* * If no window to receive the character, then toss it. */ kbd_wid = who_top_at(SM_Mouse_Pos); if ( kbd_wid == NO_WINDOW ) return; if ( not ( wtbl[kbd_wid]->wn_Evmask & KBD_ENABLE ) ) return; /* * Map character, based on the * current state of the shift, control, * meta and lock flags. */ if (shift & CTS) { if (s==SS1 || s==LET) /* Normal Ctrl map */ c = umaptab[c]&0x1F; /* Clear bits 5-6 */ else return; /* Ignore this char */ } else if (s &= shift) { if (shift & SES) { /* if shift on */ if (s & (CPLS|NMLS)) /* if caps/num lock */ c = lmaptab[c]; /* use unshifted */ else c = umaptab[c]; /* use shifted */ } else { /* if shift not on */ if (s & (CPLS|NMLS)) /* if caps/num lock */ c = umaptab[c]; /* use shifted */ else c = lmaptab[c]; /* use unshifted */ } } else c = lmaptab[c]; /* use unshifted */ /* * Act on character. */ if (c == XXX) return; /* char to ignore */ if (c != SPC) { /* not special char? */ #ifdef DOALT if (shift & ALS) /* ALT (meta bit)? */ c |= 0x80; /* set meta */ #endif gen_msg(r, c, shift); } else isspecial(r); /* special chars */ } /* * Handle special input sequences. * The character passed is the key number. * * The keypad is translated by the following table, * the first entry is the normal sequence, the second the shifted, * and the third the alternate keypad sequence. */ static char keypad[] = { '*', /* 55 */ '\0', /* 88 */ ',', /* 89 */ '/', /* 90 */ '7', /* 71 */ '8', /* 72 */ '9', /* 73 */ '4', /* 75 */ '5', /* 76 */ '6', /* 77 */ '1', /* 79 */ '2', /* 80 */ '3', /* 81 */ '0', /* 82 */ '.' /* 83 */ }; isspecial(key) register int key; { register int c; c = key; switch (key) { case 59: case 60: case 61: case 62: case 63: /* F1 - F5 */ case 64: case 65: case 66: case 67: case 68: /* F6 - F10 */ case 84: case 86: case 87: case 69: /* HELP, F12, F13, F14 */ case 70: /* F15 (Scroll Lock)*/ case 91: case 92: case 93: /* W1 - W3 */ case 95: case 96: case 97: case 98: /* cursor keys */ gen_msg(key, 0, shift); return; case 55: /* PF3 */ c = 87; case 88: case 89: case 90: /* PF1, PF2, PF4 */ c -= 18; case 79: /* 1/End */ case 80: /* 2/DOWN */ case 81: /* 3/PgDn */ case 82: /* 0/Ins */ case 83: /* ./Del */ --c; /* adjust code */ case 75: /* 4/LEFT */ case 76: /* 5 */ case 77: /* 6/RIGHT */ --c; /* adjust code */ case 71: /* 7/Home/Clear */ case 72: /* 8/UP */ case 73: /* 9/PgUp */ #ifndef TRACE if ( (shift&NMLS) || (shift&SES) || (!(shift&NMLS) && !(shift&SES) && (shift&AKPS)) ) c = 0; else c = keypad[c-67]; break; #else DB_dump(); break; #endif default: c = 0; break; } gen_msg(key, c, shift); } /* ** generate message to the active window manager */ gen_msg(kpos, kval, mod) unsigned kpos, kval, mod; { MESSAGE m; m.msg_Receiver = wtbl[kbd_wid]->wn_Wmgr; m.msg_Cmd = WM_CHARACTER; m.msg_Data[0] = kbd_wid << 8; m.msg_Data[0] |= kval; m.msg_Data[1] = kpos; m.msg_Data[2] = mod; sendmsg( &m ); }