📄 sm.c
字号:
if( data == LK_POWER_ERROR || data == LK_KDOWN_ERROR || data == LK_INPUT_ERROR || data == LK_OUTPUT_ERROR) { mprintf(" Keyboard error, code = %x\n",data); return(0); } if( data < LK_LOWEST ) return(0);/* * See if its a state change key */ switch ( data ) { case LOCK: sm_keyboard.lock ^= 0xffff; /* toggle */ if( sm_keyboard.lock ) sm_key_out( LK_LED_ENABLE ); else sm_key_out( LK_LED_DISABLE ); sm_key_out( LED_3 ); goto loop; case SHIFT: sm_keyboard.shift ^= 0xffff; goto loop; case CNTRL: sm_keyboard.cntrl ^= 0xffff; goto loop; case ALLUP: sm_keyboard.cntrl = sm_keyboard.shift = 0; goto loop; case REPEAT: c = sm_keyboard.last; break; 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 & 0x80 ) return (0); else return (c);}/****************************************************************** ** ** ** Routine to Position the cursor to a particular spot. ** ** ** ******************************************************************/sm_pos_cur( x, y)register int x,y;{ register struct nb1_regs *smaddr1; register struct sm_info *qp = sm_scn; if(sm_physmode) smaddr1 = (struct nb1_regs *)VS_PHYSCURSOR; else smaddr1 = (struct nb1_regs *)qmem; if(qp->smaddr ) { if( y < qp->min_cur_y || y > qp->max_cur_y ) y = qp->max_cur_y; if( x < qp->min_cur_x || x > qp->max_cur_x ) x = qp->max_cur_x; qp->cursor.x = x; /* keep track of real cursor*/ qp->cursor.y = y; /* position, indep. of mouse*/ smaddr1->nb_cur_xpos = XOFFSET + x; smaddr1->nb_cur_ypos = YOFFSET + y; }}/****************************************************************** ** ** ** Routine to scroll. ** ** ** ******************************************************************/smscroll(){ register struct sm_info *qp = sm_scn; int thirtylines = 30*1920;/* * If the mouse is on we don't scroll so that the bit map remains sane. */ if( sm_mouseon ) { qp->row = 0; return; }/* First copy 30 lines starting from the second line on the screen to the first * line on the screen. (we are moving 30 lines up one line) */ bcopy(qp->bitmap+1920,qp->bitmap,thirtylines);/* Do the same thing for the rest of the lines on the screen */ bcopy(qp->bitmap+1920+thirtylines,qp->bitmap+thirtylines,(qp->row - 30)* 1920);/* Now zero out the last two lines */ bzero(qp->bitmap+(qp->row*1920),3840);}/********************************************************************* ** ** ** Routine to initialize virtual console. This routine sets up the ** ** graphic device so that it can be used as the system console. It ** ** is invoked before autoconfig and has to do everything necessary ** ** to allow the device to serve as the system console. ** ** ** *********************************************************************/extern (*vs_gdopen)();extern (*vs_gdclose)();extern (*vs_gdselect)();extern (*vs_gdkint)();extern (*vs_gdioctl)();extern (*vs_gdstop)();smcons_init(){ sm_setup(); v_consputc = smputc; v_consgetc = smgetc; vs_gdopen = smopen; vs_gdclose = smclose; vs_gdselect = smselect; vs_gdkint = smkint; vs_gdioctl = smioctl; vs_gdstop = smstop; ws_display_type = SM_DTYPE; /* Identify SM as display device */ ws_display_units = 1; /* Say unit 0 present */}/****************************************************************** ** ** ** Routine to do the board specific setup. ** ** ** ******************************************************************/sm_setup(){ register struct nb_regs *smaddr = (struct nb_regs *)nexus; register struct nb1_regs *smaddr1 = (struct nb1_regs *)qmem; register struct nb2_regs *smaddr2 = (struct nb2_regs *)nmem; register struct sm_info *qp; char *smmem;/* * Set the line parameters on SLU line 0 for * the LK201 keyboard: 4800 BPS, 8-bit char, 1 stop bit, no parity. */ smaddr->sslpr = (SER_RXENAB | SER_KBD | SER_SPEED | SER_CHARW);/* * Initialize the screen * */ sm_scrn_init(smaddr1); cur_reg |= (HSHI | ENPA | ENPB); smaddr1->nb_cur_cmd = cur_reg; smmem = (char *)((u_long)smaddr2); if ((long)smmem != ((long)smmem & ~0x7)) printf("smmem: %x not longword aligned\n",smmem); sm_scn = (struct sm_info *)((u_int)smmem + 125*1024); qp = sm_scn; sminit_scn_def(); *sm_scn = sm_scn_defaults; qp->bitmap = smmem; qp->smaddr = smaddr; qp->cursorbits = (short *)((u_int)smmem + 127*1024);/* * Set a flag to indicate we are using VR260 */ monochrome = 1;/* * Initialize the graphic device * */ sm_init();/* * Initialize the mouse * */ sm_mouse_init();}/****************************************************************** ** ** * Routine to initialize the screen. ** ** ** ******************************************************************/sm_init(){ register int i; register char *ptr; register struct sm_info *qp = sm_scn;/* * Clear the bit map */ for( i=0 , ptr = qp->bitmap ; i<60 ; i++ , ptr += 2048) bzero( ptr, 2048 );/* * Home the cursor */ qp->row = qp->col = 0;/* * Load the cursor with the default values * */ sm_load_cursor(def_cursor);/* * Reset keyboard to default state. */ sm_key_out(LK_DEFAULTS);}smreset(){}/****************************************************************** ** ** * Routine to initialize the screen. ** ** ** ******************************************************************/sm_scrn_init(smaddr1)struct nb1_regs *smaddr1;{ register int i; DELAY(100000); /* wait */ i = FOPB | VBHI; smaddr1->nb_cur_cmd = i;}/****************************************************************** ** ** * Routine to initialize the mouse. ** ** ** ******************************************************************//* * NOTE: * This routine communicates with the mouse by directly * manipulating the VAXstar SLU registers. This is allowed * ONLY because the mouse is initialized before the system * is up far enough to need the SLU in interrupt mode. */int sm_getc();sm_mouse_init(){ register struct nb_regs *ssaddr = (struct nb_regs *)nexus; register int lpr; int i; int status; char id_byte;/* * Set SLU line 1 parameters for mouse communication. */ lpr = SER_POINTER | SER_CHARW | SER_PARENB | SER_ODDPAR | SER_SPEED | SER_RXENAB; ssaddr->sslpr = lpr;/* * Perform a self-test */ sm_putc(SELF_TEST);/* * Wait for the first byte of the self-test report * */ status = sm_getc(); if (status < 0) { mprintf("\nsm: Timeout on 1st byte of self-test report\n"); goto OUT; }/* * Wait for the hardware ID (the second byte returned by the self-test report) * */ id_byte = sm_getc(); if (id_byte < 0) { mprintf("\nsm: Timeout on 2nd byte of self-test report\n"); goto OUT; }/* * Wait for the third byte returned by the self-test report) * */ status = sm_getc(); if (status != 0) { mprintf("\nsm: Timeout on 3rd byte of self-test report\n"); goto OUT; }/* * Wait for the forth byte returned by the self-test report) * */ status = sm_getc(); if (status != 0) { mprintf("\nsm: Timeout on 4th byte of self-test report\n"); goto OUT; }/* * Wait to be sure that the self-test is done (documentation indicates that * it requires 1 second to do the self-test). */ DELAY(1000000);/* * Set the operating mode * * We set the mode for both mouse and the tablet to "Incremental stream mode". * */ if ((id_byte & 0x0f) == MOUSE_ID) sm_pointer_id = MOUSE_ID; else sm_pointer_id = TABLET_ID; sm_putc(INCREMENTAL);OUT: return(0);}/****************************************************************** ** ** ** Routine to get 1 character from the mouse (SLU line 1). ** ** Return an error on timeout or faulty character. ** ** ** ** NOTE: ** ** This routine will be used just during initialization ** ** (during system boot). ** ** ** ******************************************************************/sm_getc(){ register struct nb_regs *ssaddr = (struct nb_regs *)nexus; register int timo; register int c; for(timo=50; timo > 0; --timo) { DELAY(50000); if(ssaddr->sscsr&SS_RDONE) { c = ssaddr->ssrbuf; if(((c >> 8) & 03) != 1) continue; if(c&(SS_DO|SS_FE|SS_PE)) continue; return(c & 0xff); } } return(-1);}/****************************************************************** ** ** ** Routine to send a character to the mouse using SLU line 1. ** ** ** ** NOTE: ** ** This routine will be used just during initialization ** ** (during system boot). ** ** ** ******************************************************************/sm_putc(c) register int c;{ register struct nb_regs *ssaddr = (struct nb_regs *)nexus; register int timo; ssaddr->sstcr |= 0x2; timo = 60000; while ((ssaddr->sscsr&SS_TRDY) == 0) if (--timo == 0) break; ssaddr->sstbuf = c&0xff; DELAY(50000); /* ensure character transmit completed */ ssaddr->sstcr &= ~0x2;}/****************************************************************** ** ** ** Routine to output a character to the LK201 keyboard. This ** ** routine polls the tramsmitter on the keyboard to output a ** ** code. The timer is to avaoid hanging on a bad device. ** ** ** ******************************************************************//* * 3/5/89 -- Fred Canter * Bug fix for stray interrupts thru SCB vector 0x1fc. * Turn interrupts off while polling for xmit ready when * sending characters to the keyboard. */sm_key_out( c )char c;{ register struct sm_info *qp = sm_scn; register struct nb_regs *ssaddr; register int timo = 30000; int s; int tcr, ln; int int_msk; if(qp->smaddr == 0) return; if(sm_physmode) ssaddr = (struct nb_regs *)VS_PHYSNEXUS; else ssaddr = (struct nb_regs *)nexus; if(sm_physmode == 0) { s = spl5(); int_msk = ssaddr->nb_int_msk; ssaddr->nb_int_msk &= ~SINT_ST; } tcr = 0; ssaddr->sstcr |= 1; while (1) { while ((ssaddr->sscsr&SS_TRDY) == 0 && timo--) ; ln = (ssaddr->sscsr>>8) & 3; if (ln != 0) { tcr |= (1 << ln); ssaddr->sstcr &= ~(1 << ln); continue; } ssaddr->sstbuf = c&0xff; while (1) { while ((ssaddr->sscsr&SS_TRDY) == 0) ; ln = (ssaddr->sscsr>>8) & 3; if (ln != 0) { tcr |= (1 << ln); ssaddr->sstcr &= ~(1 << ln); continue; } break; } ssaddr->sstcr &= ~0x1; if (tcr == 0) ssaddr->nb_int_reqclr = SINT_ST; else ssaddr->sstcr |= tcr; break; } if(sm_physmode == 0) { if (int_msk & SINT_ST) ssaddr->nb_int_msk |= SINT_ST; splx(s); }}/****************************************************************** ** ** ** Routine to load the cursor sprite pattern. ** ** ** ******************************************************************//* * 3/5/89 -- Fred Canter * Bug fix for stray interrupts thru SCB vector 0x1fc. * Removed waitef routine and moved the code in-line because * waitef was only called from sm_load_cursor. * Removed clear of video EOF interrupt request bit. */int sm_waitef_on = 0; /* If 1, sync cursor load with vert. EOF intr */sm_load_cursor(cur)unsigned short cur[32];{ register struct nb1_regs *smaddr1 = (struct nb1_regs *)qmem; register struct nb_regs *smaddr = (struct nb_regs *)nexus; register int i; int j;/* waitef(); *//* smaddr->nb_int_reqclr = SINT_VF; */ if (sm_waitef_on) { for (j = 1000000; j > 0; --j) { if (smaddr->nb_int_reqclr & SINT_VF) break; } if (j <= 0) { mprintf("\nsm: timeout polling for end-of-frame interrupt\n"); } } cur_reg |= LODSA; smaddr1->nb_cur_cmd = cur_reg; for (i = 0; i < 32; ++i) smaddr1->nb_load = cur[i]; cur_reg &= ~LODSA; smaddr1->nb_cur_cmd = cur_reg;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -