📄 sm.c
字号:
case SHIFT: sm_keyboard.shift ^= 0xffff; return; case CNTRL: sm_keyboard.cntrl ^= 0xffff; return; case ALLUP: sm_keyboard.cntrl = sm_keyboard.shift = 0; return; case REPEAT: c = sm_keyboard.last; break; case HOLD:/* * "Hold Screen" key was pressed, we treat it as if ^s or ^q was typed. */ if (sm_keyboard.hold == 0) { if((tp->t_state & TS_TTSTOP) == 0) { c = q_key[CHAR_S]; sm_key_out( LK_LED_ENABLE ); sm_key_out( LED_4 ); sm_keyboard.hold = 1; } else c = q_key[CHAR_Q]; } else { c = q_key[CHAR_Q]; sm_key_out( LK_LED_DISABLE ); sm_key_out( LED_4 ); sm_keyboard.hold = 0; } if( c >= ' ' && c <= '~' ) c &= 0x1f; else if (c >= 0xA1 && c <= 0xFE) c &= 0x9F; (*linesw[tp->t_line].l_rint)(c, tp); return; default:/* * Test for control characters. If set, see if the character * is elligible to become a control character. */ if( sm_keyboard.cntrl ) { c = q_key[ data ]; if( c >= ' ' && c <= '~' ) c &= 0x1f; } else if( sm_keyboard.lock || sm_keyboard.shift ) c = q_shift_key[ data ]; else c = q_key[ data ]; break; } sm_keyboard.last = c;/* * Check for special function keys */ if( c & 0x100 ) { register char *string; string = q_special[ c & 0x7f ]; while( *string ) (*linesw[tp->t_line].l_rint)(*string++, tp); } else { if (tp->t_iflag & ISTRIP) /* Strip to 7 bits. */ c &= 0177; else { /* Take the full 8-bits */ /* * If ISTRIP is not set a valid character of 377 * is read as 0377,0377 to avoid ambiguity with * the PARMARK sequence. */ if ((c == 0377) && (tp->t_line == TERMIODISC) && (tp->t_iflag & PARMRK)) (*linesw[tp->t_line].l_rint)(0377,tp); } (*linesw[tp->t_line].l_rint)(c, tp); } if (sm_keyboard.hold &&((tp->t_state & TS_TTSTOP) == 0)) { sm_key_out( LK_LED_DISABLE ); sm_key_out( LED_4 ); sm_keyboard.hold = 0; } } } return(0);} /* smkint *//****************************************************************** ** ** ** Graphic device ioctl routine. ** ** ** ******************************************************************//*ARGSUSED*/smioctl(dev, cmd, data, flag) dev_t dev; register caddr_t data;{ register struct tty *tp; register int unit = minor(dev); register struct sm_info *qp = sm_scn; register struct sm_kpcmd *qk; register unsigned char *cp; struct nb1_regs *smaddr1; int error; int i; struct devget *devget; /* * Check for and process VAXstar monochrome specific ioctl's */ switch( cmd ) { case QIOCGINFO: /* return screen info */ bcopy(qp, data, sizeof (struct sm_info)); break; case QIOCSMSTATE: /* set mouse state */ qp->mouse = *((smCursor *)data); sm_pos_cur( qp->mouse.x, qp->mouse.y ); break; case QIOCINIT: /* init screen */ sm_init(); break; case QIOCKPCMD: qk = (struct sm_kpcmd *)data; if(qk->nbytes == 0) qk->cmd |= 0200; if(sm_mouseon == 0) qk->cmd |= 1; /* no mode changes */ sm_key_out(qk->cmd); cp = &qk->par[0]; while(qk->nbytes-- > 0) { /* terminate parameters */ if(qk->nbytes <= 0) *cp |= 0200; sm_key_out(*cp++); } break; case QIOCADDR: /* get struct addr */ *(struct sm_info **) data = qp; break; case QIOVIDEOON: /* turn on the video */ smaddr1 = (struct nb1_regs *)qmem; cur_reg &= ~FOPB; cur_reg |= ENPA; smaddr1->nb_cur_cmd = cur_reg; break; case QIOVIDEOOFF: /* turn off the video */ smaddr1 = (struct nb1_regs *)qmem; cur_reg |= FOPB; cur_reg &= ~(ENPA | FOPA); smaddr1->nb_cur_cmd = cur_reg; break; case QIOWCURSOR: /* Write cursor bit map */ sm_load_cursor(data); break; case QIOKERNLOOP: /* redirect kernel console output */ sm_kern_loop = -1; break; case QIOKERNUNLOOP: /* don't redirect kernel console output */ case QD_KERN_UNLOOP: /* duplicate, called from inside kernel */ sm_kern_loop = 0; break;#ifdef debby case QIODISPON: /* display on */ { register struct nb1_regs *smaddr1 = (struct nb1_regs *)qmem; cur_reg |= ENPA; cur_reg &= ~(FOPB); smaddr1->nb_cur_cmd = cur_reg; break; } case QIODISPOFF: /* display on */ { register struct nb1_regs *smaddr1 = (struct nb1_regs *)qmem; cur_reg |= FOPB; cur_reg &= ~(ENPA); smaddr1->nb_cur_cmd = cur_reg; break; }#endif case DEVIOCGET: /* device status */ devget = (struct devget *)data; bzero(devget,sizeof(struct devget)); devget->category = DEV_TERMINAL; /* terminal cat.*/ devget->bus = DEV_NB; /* NO bus */ bcopy(DEV_VS_SLU,devget->interface, strlen(DEV_VS_SLU)); /* interface */ if(unit == 0) bcopy(DEV_VR260,devget->device, strlen(DEV_VR260)); /* device */ else if(sm_pointer_id == MOUSE_ID) bcopy(DEV_MOUSE,devget->device, strlen(DEV_MOUSE)); else if(sm_pointer_id == TABLET_ID) bcopy(DEV_TABLET,devget->device, strlen(DEV_TABLET)); else bcopy(DEV_UNKNOWN,devget->device, strlen(DEV_UNKNOWN)); devget->adpt_num = 0; /* NO adapter */ devget->nexus_num = 0; /* fake nexus 0 */ devget->bus_num = 0; /* NO bus */ devget->ctlr_num = 0; /* cntlr number */ devget->slave_num = unit; /* line number */ bcopy("sm",devget->dev_name, 3); /* Ultrix "sm" */ devget->unit_num = unit; /* ss line? */ /* TODO: should say not supported instead of zero! */ devget->soft_count = 0; /* soft err cnt */ devget->hard_count = 0; /* hard err cnt */ devget->stat = 0; /* status */ devget->category_stat = 0; /* cat. stat. */ break; default: /* not ours ?? */ if ((unit == 2) && (major(dev) == CONSOLEMAJOR)) tp = &sm_tty; else tp = &ss_tty[unit]; error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); if (error >= 0) return (error); error = ttioctl(tp, cmd, data, flag); if (error >= 0) { return (error); } /* if error = -1 then ioctl does not exist */ if (u.u_procp->p_progenv == A_POSIX) return (EINVAL); return (ENOTTY); break; } return (0);}/****************************************************************** ** ** ** Graphic device End-Of-Frame interrupt Routine. ** ** ** ******************************************************************/#define SM_TIME1 100#define SM_TIME2 500#define SM_MAX_LOOP 10200int sm_max_loop = SM_MAX_LOOP;int sm_time2 = SM_TIME2;int sm_time1 = SM_TIME1;smvint(sm) int sm;{ register struct sm_info *qp = sm_scn;/* * Test and set the sm_ipl_lo flag. If the result is not zero then * someone else must have already gotten here. */ if( --sm_ipl_lo ) return; qp->qe.timestamp_ms = TOY; sm_ipl_lo = 1;}/****************************************************************** ** ** ** Routine to start transmission. ** ** ** ******************************************************************/smstart(tp) register struct tty *tp;{ register int unit, c; register struct tty *tp0; int s; unit = minor(tp->t_dev); tp0 = &sm_tty; unit &= 03; s = spl5();/* * If it's currently active, or delaying, no need to do anything. */ if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) goto out;/* * Display chars until the queue is empty, if the second subchannel is open * direct them there. Drop characters from any lines other than 0 on the floor. * TANDEM is set on second subchannel for flow control. */ while( tp->t_outq.c_cc ) { if (unit == 0) { /* console device */ if (tp0->t_state & TS_ISOPEN) { if (tp0->t_state & TS_TBLOCK) goto out; c = getc(&tp->t_outq); (*linesw[tp0->t_line].l_rint)(c, tp0); } else { c = getc(&tp->t_outq); sm_blitc( c & 0xff ); } } else if (unit == 2) { /* smscreen, do flow control */ c = getc(&tp->t_outq); if ((tp0->t_state&TS_TBLOCK) == 0) { tp = &ss_tty[0]; unit = minor(tp->t_dev); unit &= 3; continue; } else goto out; } else c = getc(&tp->t_outq); }/* * Position the cursor to the next character location. */ if (!(sm_dev_inuse & GRAPHIC_DEV)) sm_pos_cur( sm_scn->col*8, sm_scn->row*15 );/* * If there are sleepers, and output has drained below low * water mark, wake up the sleepers. */ if ( tp->t_outq.c_cc<=TTLOWAT(tp) ) if (tp->t_state&TS_ASLEEP){ tp->t_state &= ~TS_ASLEEP; wakeup((caddr_t)&tp->t_outq); } tp->t_state &= ~TS_BUSY;out: splx(s);}/****************************************************************** ** ** ** Routine to stop output on the graphic device, e.g. for ^S/^Q ** ** or output flush. ** ** ** ******************************************************************//*ARGSUSED*/smstop(tp, flag) register struct tty *tp;{ register int s;/* * Block interrupts while modifying the state. */ s = spl5(); if (tp->t_state & TS_BUSY) if ((tp->t_state&TS_TTSTOP)==0) tp->t_state |= TS_FLUSH; else tp->t_state &= ~TS_BUSY; splx(s);}/****************************************************************** ** ** ** Routine to output a character to the screen ** ** ** ******************************************************************/sm_blitc( c )register u_char c;{ register char *b_row, *f_row; register int i; register int ote = 128; register struct sm_info *qp = sm_scn; c &= 0xff; switch ( c ) { case '\t': /* tab */ for( i = 8 - (qp->col & 0x7) ; i > 0 ; i-- ) sm_blitc( ' ' ); return(0); case '\r': /* return */ qp->col = 0; return(0); case '\b': /* backspace */ if( --qp->col < 0 ) qp->col = 0; return(0); case '\n': /* linefeed */ if( qp->row+1 >= qp->max_row ) smscroll(); else qp->row++;/* * Position the cursor to the next character location. */ if (!(sm_dev_inuse & GRAPHIC_DEV)) sm_pos_cur( qp->col*8, qp->row*15 ); return(0); case '\007': /* bell *//* * We don't do anything to the keyboard until after autoconfigure. */ if( qp->smaddr ) sm_key_out( LK_RING_BELL ); return(0); default: /* * xA1 to XFD are the printable characters added with 8-bit * support. */ if(( c >= ' ' && c <= '~' ) || ( c >= 0xA1 && c <= 0xFD)) { b_row = qp->bitmap+(qp->row*15 & 0x3ff)*128+qp->col; i = c - ' '; if( i < 0 || i > 221 ) i = 0; else { /* These are to skip the (32) 8-bit * control chars, as well as DEL * and 0xA0 which aren't printable */ if (c > '~') i -= 34; i *= 15; } f_row = (char *)((int)q_font + i);/* inline expansion for speed */ *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; *b_row = *f_row++; b_row += ote; if( ++qp->col >= qp->max_col ) { qp->col = 0 ; if( qp->row+1 >= qp->max_row ) smscroll(); else qp->row++; } } return(0); }}/******************************************************************** ** ** ** Routine to direct kernel console output to display destination ** ** ** ********************************************************************/smputc( c )register char c;{ register struct tty *tp0; register struct sm_info *qp; register struct nb1_regs *smaddr1;/* * This routine may be called in physical mode by the dump code * so we change the driver into physical mode. * One way change, can't go back to virtual mode. */ if( (mfpr(MAPEN) & 1) == 0 ) { sm_physmode = 1; sm_mouseon = 0; if (cur_reg & FOPB) { /* user must have turned the screen off */ smaddr1 = (struct nb1_regs *)VS_PHYSCURSOR; cur_reg |= ENPA; cur_reg &= ~(FOPB); smaddr1->nb_cur_cmd = cur_reg; } sm_scn = (struct sm_info *)((u_int)VS_PHYSBITMAP + 125*1024); qp = sm_scn; qp->version = 11; qp->bitmap = (char *)((u_long)VS_PHYSBITMAP); sm_blitc(c & 0xff); return; }/* * direct kernel output char to the proper place */ tp0 = &sm_tty; if (sm_kern_loop != 0 && tp0->t_state & TS_ISOPEN) { (*linesw[tp0->t_line].l_rint)(c, tp0); } else { sm_blitc(c & 0xff); }}/****************************************************************** ** ** ** Routine to get a character from LK201. ** ** ** ******************************************************************/int ssgetc();smgetc(){ int c; u_short data;/* * Get a character from the keyboard, */loop: data = ssgetc();/* * Check for various keyboard errors */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -