📄 ps2drivr.c
字号:
/************************************************************* * File: lib/ps2drivr.c * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970304 Start of revision history */#include <mips.h>#include <terms.h>#include <string.h>#include <screen.h>/* * PMON console driver for RacerX LR33020 board. Uses PS2 port for * keyboard input, and video interface for output. *//* major selection switches */#define VT100EM /* include vt100 emulation *//* #define USE_MACROS /* use macros instead of functions */#define SCRN_SAVER /* implement the screen saver feature */#define DRIVE_LEDS /* include code to drive keyboard LEDs *//* key scan codes */#define NUM_LOCK 0x77#define CAPS_LOCK 0x58#define LSHIFT 0x12#define RSHIFT 0x59#define CTRL_KEY 0x14#define BRK_PRFX 0xf0 /* prefix code sent on key release (break) */#define SCROLL_LED 0x01#define NUM_LED 0x02#define CAPS_LED 0x04#define XMAX SCRN_WIDTH /* screen width in pixels */#define YMAX SCRN_HEIGHT /* screen height in pixels */#define LNSPACE 13 /* vertical line spacing */#define CHSPACE 8 /* horizontal char spacing */#define FOREGROUND 1 /* foreground color */#define BACKGROUND 0 /* background color */#define TIMEOUT 35000000 /* timeout value for screen saver (10 mins) */#ifdef USE_MACROS#define pixel(x,y,color) (*((char *)(SCRN_BASE+(x)+(XMAX*(y)))) = color)#define rd_pixel(x,y) (*((char *)(SCRN_BASE+(x)+(XMAX*(y)))))#endif/* convert scan codes to ascii non shifted */char u_keycode[] = {/* 00 */ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x4d,/* 08 */ 0x42,0x20,0x20,0x20,0x20,0x09,0x60,0x3c,/* 10 */ 0x20,0x00,0x20,0x20,0x20,0x71,0x31,0x3e,/* 18 */ 0x20,0x20,0x7a,0x73,0x61,0x77,0x32,0x3f,/* 20 */ 0x20,0x63,0x78,0x64,0x65,0x34,0x33,0x00,/* 28 */ 0x20,0x20,0x76,0x66,0x74,0x72,0x35,0x00,/* 30 */ 0x20,0x6e,0x62,0x68,0x67,0x79,0x36,0x00,/* 38 */ 0x20,0x21,0x6d,0x6a,0x75,0x37,0x38,0x00,/* 40 */ 0x20,0x2c,0x6b,0x69,0x6f,0x30,0x39,0x0a,/* 48 */ 0x20,0x2e,0x2f,0x6c,0x3b,0x70,0x2d,0x2f,/* 50 */ 0x20,0x20,0x27,0x20,0x5b,0x3d,0x2a,0x25,/* 58 */ 0x20,0x00,0x0d,0x5d,0x20,0x5c,0x20,0x30,/* 60 */ 0x49,0x45,0x32,0x55,0x09,0x54,0x08,0x08,/* 68 */ 0x20,0x44,0x20,0x53,0x41,0x50,0x52,0x4f,/* 70 */ 0x4c,0x20,0x4b,0x4a,0x20,0x48,0x1b,0x47,/* 78 */ 0x20,0x2b,0x20,0x2d,0x2a,0x22,0x3a,0x20 };/* convert scan codes to ascii shifted */char s_keycode[] = {/* 00 */ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,/* 08 */ 0x20,0x20,0x20,0x20,0x20,0x09,0x7e,0x20,/* 10 */ 0x20,0x00,0x20,0x20,0x20,0x51,0x21,0x20,/* 18 */ 0x20,0x0a,0x5a,0x53,0x41,0x57,0x40,0x20,/* 20 */ 0x20,0x43,0x58,0x44,0x45,0x24,0x23,0x20,/* 28 */ 0x20,0x2f,0x56,0x46,0x54,0x52,0x25,0x20,/* 30 */ 0x20,0x4e,0x42,0x48,0x47,0x59,0x5e,0x20,/* 38 */ 0x20,0x2a,0x4d,0x4a,0x55,0x26,0x2a,0x20,/* 40 */ 0x20,0x3c,0x4b,0x49,0x4f,0x29,0x28,0x20,/* 48 */ 0x20,0x3e,0x3f,0x4c,0x3a,0x50,0x5f,0x20,/* 50 */ 0x20,0x20,0x22,0x20,0x7b,0x2b,0x20,0x20,/* 58 */ 0x20,0x00,0x0d,0x7d,0x20,0x7c,0x20,0x20,/* 60 */ 0x49,0x00,0x20,0x00,0x00,0x00,0x08,0x00,/* 68 */ 0x20,0x00,0x69,0x00,0x79,0x66,0x00,0x6e,/* 70 */ 0x69,0x00,0x66,0x6e,0x20,0x49,0x1b,0x00,/* 78 */ 0x20,0x2b,0x20,0x2d,0x2a,0x69,0x6e,0x20 };extern char chlist[][11];#ifdef SCRN_SAVERint timeout;#endif#ifdef LR33020/************************************************************** ps2driver(op,st,chan,ch)*/ps2driver(op,st,chan,ch)int op,chan,ch;struct ps2struct *st;{switch (op) { case OP_RXRDY : return(do_rxrdy(st)); break; case OP_RX : return(st->rxbuf); break; case OP_TXRDY : return(1); break; case OP_TX : do_tx(st,ch); break; case OP_INIT : clr_scrn(BACKGROUND); st->curx = 0; st->cury = 11; st->led_state = 0; st->sh_state = 0; st->ctrl_state = 0; st->prev = 0; wr_cursor(st->curx,st->cury); initkeybd(); break; case OP_BAUD : break; }return(0);}/************************************************************** initkeybd()*/initkeybd(){int i,c;wrpscomm(0xff,0); /* clear all bits *//* make sure the rx buffer is empty */while (cfc2(C2_PSSTAT) & PSSTAT_RXBF) mfc2(C2_PSRCVB);/* issue the reset command */putkeybd(0xff); if ((c=getkeybd()) != 0xfa) printf("[0%02x]",c);/* signal acceptance of the ACK */wrpscomm(0,PSCOMM_CLKINH);for (i=0;i<14000;i++) /* delay at least 500 usecs */ ;wrpscomm(PSCOMM_CLKINH,0);/* wait for completion of the BAT */if ((c=getkeybd()) != 0xaa) printf("[1%02x]",c);}/************************************************************** getkeybd()*/getkeybd(){int c;while (!(cfc2(C2_PSSTAT) & PSSTAT_RXBF)) ;c = mfc2(C2_PSRCVB)&0xff;return(c);}/************************************************************** do_rxrdy(st)*/do_rxrdy(st)struct ps2struct *st;{int c;for (;;) {#ifdef SCRN_SAVER if (!(cfc2(C2_PSSTAT) & PSSTAT_RXBF)) { if (timeout == TIMEOUT) blank_scrn(st); if (timeout <= TIMEOUT) timeout++; return(0); } if (timeout >= TIMEOUT) unblank_scrn(st); timeout = 0;#else if (!(cfc2(C2_PSSTAT) & PSSTAT_RXBF)) return(0);#endif c = mfc2(C2_PSRCVB)&0xff; if (c == BRK_PRFX || c == 0xe0) ; else if (c == LSHIFT || c == RSHIFT) { if (st->prev == BRK_PRFX) st->sh_state = 0; else st->sh_state = 1; } else if (c == CTRL_KEY) { if (st->prev == BRK_PRFX) st->ctrl_state = 0; else st->ctrl_state = 1; } else if (c == CAPS_LOCK) { if (st->prev == BRK_PRFX) { st->led_state ^= CAPS_LED; setleds(st->led_state); } } else if (c == NUM_LOCK) { if (st->prev == BRK_PRFX) { st->led_state ^= NUM_LED; setleds(st->led_state); } } else if (st->prev == BRK_PRFX) ; else { if (st->sh_state == 1) c = s_keycode[c]; else c = u_keycode[c]; if (st->ctrl_state == 1) { if (c == '-') c = '_'; else if (c == '2') c = '@'; else if (c == '6') c = '^'; c &= 0x1f; } if (isalpha(c) && st->led_state&CAPS_LED) { if (st->sh_state == 1) c |= 0x20; else c &= ~0x20; } st->rxbuf = c; return(1); } st->prev = c; }}/************************************************************** setleds(n)*/setleds(n)int n;{int c;#ifdef DRIVE_LEDSputkeybd(0xed); if ((c=getkeybd()) != 0xfa) printf("[2%02x]",c);putkeybd(n); if ((c=getkeybd()) != 0xfa) printf("[3%02x]",c);#endif}/************************************************************** putkeybd(c)*/putkeybd(c)int c;{int i;while (!(cfc2(C2_PSSTAT) & PSSTAT_TXBE)) ; /* wait while TX buf not empty */while (cfc2(C2_PSSTAT) & PSSTAT_RXIN) ; /* wait while RX not busy */mtc2(C2_PSTXB,c); /* load TX buf */wrpscomm(0,PSCOMM_CLKINH); /* set CLKINH */for (i=0;i<1000;i++) ; /* wait a while */wrpscomm(0,PSCOMM_TXEN); /* set TXEN */wrpscomm(PSCOMM_CLKINH,0); /* clear CLKINH */while (!(cfc2(C2_PSSTAT) & PSSTAT_TXBE)) ; /* wait while TX buf not empty */wrpscomm(PSCOMM_TXEN,0); /* clear TXEN */}/************************************************************** wrpscomm(clr,set)*/wrpscomm(clr,set)int clr,set;{int t;t = cfc2(C2_PSCOMM); t &= ~clr; t |= set;ctc2(C2_PSCOMM,t);}/************************************************************** do_tx(st,c)*/do_tx(st,c)struct ps2struct *st;int c;{int j,k,x,y;char b,*p;#ifdef VT100EMif (vt100em(st,c)) return;#endifif (c == '\b') { /* move to glib */ wr_cursor(st->curx,st->cury); /* erase cursor */ st->curx -= 8; wr_cursor(st->curx,st->cury); return; }if (c == '\r') { wr_cursor(st->curx,st->cury); /* erase cursor */ st->curx = 0; wr_cursor(st->curx,st->cury); return; }if (c == '\n') { wr_cursor(st->curx,st->cury); /* erase cursor */ st->cury += LNSPACE; if (st->cury > YMAX-LNSPACE) { scroll_up(); st->cury -= LNSPACE; } wr_cursor(st->curx,st->cury); return; }x = st->curx;y = st->cury;p = chlist[c];for (j=10;j>=0;j--) { b = p[j]; for (k=7;k>=0;k--) { if ((b & 1) == 1) pixel(x+k,y+j-9,FOREGROUND); else pixel(x+k,y+j-9,BACKGROUND); b = b>>1; } }st->curx += 8;if (st->curx > 127*8) { /* line wrap */ st->curx = 0; st->cury += LNSPACE; if (st->cury > YMAX-LNSPACE) { scroll_up(); st->cury -= LNSPACE; } }wr_cursor(st->curx,st->cury);}#ifdef VT100EMint cursor_off;char emstr[10];vt100em(st,c)struct ps2struct *st;int c;{char tmp[12],*p,*q;char *digits = "0123456789";if (strlen(emstr) == 0 && c != '\033') return(0);if (c == '\033') *emstr = 0;strccat(emstr,c);if (strequ("\033[H",emstr)) { /* home */ wr_cursor(st->curx,st->cury); /* erase cursor */ st->curx = 0; st->cury = 0; wr_cursor(st->curx,st->cury); *emstr = 0; }else if (strequ("\033[J",emstr)) { /* clear */ clr_scrn(BACKGROUND); *emstr = 0; }else if (strequ("\033[?25l",emstr)) { /* cur_off */ wr_cursor(st->curx,st->cury); /* erase cursor */ cursor_off = 1; *emstr = 0; }else if (strequ("\033[?25h",emstr)) { /* cur_on */ cursor_off = 0; wr_cursor(st->curx,st->cury); *emstr = 0; }else if (strpat(emstr,"\033[*;*H")) { /* cm */ if (!(p=strpbrk(emstr,digits))) { *emstr = 0; return(1); } if (!(q=strchr(p,';'))) { *emstr = 0; return(1); } strncpy(tmp,p,q-p); wr_cursor(st->curx,st->cury); /* erase cursor */ st->cury = (atoi(tmp)-1)*LNSPACE; if (!(p=strpbrk(q,digits))) { *emstr = 0; return(1); } if (!(q=strchr(p,'H'))) { *emstr = 0; return(1); } strncpy(tmp,p,q-p); st->curx = (atoi(tmp)-1)*CHSPACE; wr_cursor(st->curx,st->cury); *emstr = 0; }if (strlen(emstr) >= 9) *emstr = 0; /* safety net */return(1);}#endif#ifndef USE_MACROS/************************************************************** pixel(x,y,color)*/pixel(x,y,color)int x,y,color;{char *p;p = (char *)(SCRN_BASE+x+(XMAX*y));*p = color;}/************************************************************** rd_pixel(x,y)*/rd_pixel(x,y)int x,y;{char *p;p = (char *)(SCRN_BASE+x+(XMAX*y));return(*p);}#endif/************************************************************** clr_scrn(color)*/clr_scrn(color)int color;{int i;char *p;p = (char *)SCRN_BASE;for (i=0;i<YMAX*XMAX;i++) { *p++ = color;/* if ((i%1000)==0) scandevs(); */ }}/************************************************************** scroll_up()*/scroll_up(){unsigned long *s,*d;int j;d = (unsigned long *)SCRN_BASE;s = (unsigned long *)(SCRN_BASE+(XMAX*LNSPACE));for (j=0;j<(YMAX*XMAX)-(XMAX*LNSPACE);j+=16) { *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; if ((j%730) == 0) scandevs(); /* don't drop chars */ }}/************************************************************** wr_cursor()*/wr_cursor(x,y)int x,y;{int j,k;#ifdef VT100EMif (cursor_off) return;#endiffor (j=10;j>=0;j--) { for (k=7;k>=0;k--) { if (rd_pixel(x+k,y+j-9) == BACKGROUND) pixel(x+k,y+j-9,FOREGROUND); else pixel(x+k,y+j-9,BACKGROUND); } }}#ifdef SCRN_SAVER#define BROOKTREE ((int *)0xbd000000)int btcmd_save;blank_scrn(st) struct ps2struct *st;{BROOKTREE[0] = 0x06; /* select the command register */btcmd_save = BROOKTREE[2]; /* save existing value */BROOKTREE[2] = 0x00; /* write to it */}unblank_scrn(st) struct ps2struct *st;{BROOKTREE[0] = 0x06; /* select the command register */BROOKTREE[2] = btcmd_save; /* restore the cmd reg */}#endif#else /* some toolsets don't like empty files */ps2driver_dummy() {}#endif /* LR33020 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -