📄 qv.c
字号:
} } qp->mouse.x += dx; qp->mouse.y -= dy; if( qp->mouse.x < qp->min_cur_x ) qp->mouse.x = qp->min_cur_x; if( qp->mouse.y < qp->min_cur_y ) qp->mouse.y = qp->min_cur_y; if( qp->mouse.x > qp->max_cur_x ) qp->mouse.x = qp->max_cur_x; if( qp->mouse.y > qp->max_cur_y ) qp->mouse.y = qp->max_cur_y; if( tp0->t_state & TS_ISOPEN ) qv_pos_cur( qp->mouse.x, qp->mouse.y ); if (qp->mouse.y < qp->mbox.bottom && qp->mouse.y >= qp->mbox.top && qp->mouse.x < qp->mbox.right && qp->mouse.x >= qp->mbox.left) goto mbuttons; qp->mbox.bottom = 0; /* trash box */ /* reset the AND/OR bit so cursor currect for new location *//* qp->qvaddr->qv_csr |= QV_CUR_MODE;*/ if (EVROUND(qp->qe.eTail + 1) == qp->qe.eHead) goto mbuttons; i = EVROUND (qp->qe.eTail - 1); if ((qp->qe.eTail != qp->qe.eHead) && ( i != qp->qe.eHead)) { qep = &qp->qe.events[i]; if(qep->type == QV_MMOTION) { qep->x = qp->mouse.x; qep->y = qp->mouse.y; qep->time = TOY; qep->device = QV_MOUSE; goto mbuttons; } }/* * Put event into queue and do select */ qep = &qp->qe.events[qp->qe.eTail]; qep->type = QV_MMOTION; qep->time = TOY; qep->x = qp->mouse.x; qep->y = qp->mouse.y; qep->device = QV_MOUSE; qp->qe.eTail = EVROUND(qp->qe.eTail + 1); } } /* * See if mouse switches have changed. */mbuttons:if( om_switch != ( m_switch = (qvaddr->qv_csr & QV_MOUSE_ANY) >> 8 ) ) { qp->mswitches = ~m_switch & 0x7; for (j = 0; j < 3; j++) { /* check each switch */ if ( ((om_switch>>j) & 1) == ((m_switch>>j) & 1) ) continue; /* check for room in the queue */ if ((i = EVROUND(qp->qe.eTail+1)) == qp->qe.eHead) { qv_ipl_lo = 1 ; return(0); } qep = &qp->qe.events[qp->qe.eTail]; /* put event into queue and do select */ qep->type = QV_BUTTON; qep->key = 2 - j; qep->direction = QV_KBTDOWN; if ( (m_switch >> j) & 1) qep->direction = QV_KBTUP; qep->device = QV_MOUSE; qep->time = TOY; qep->x = qp->mouse.x; qep->y = qp->mouse.y; qp->qe.eTail = i; } om_switch = m_switch; qp->mswitches = m_switch; } if (rsel && (qp->qe.eHead != qp->qe.eTail)) { selwakeup(rsel,0); rsel = 0; } /* * Okay we can take another hit now */ qv_ipl_lo = 1;}/* * Start transmission */qvstart(tp) register struct tty *tp;{ register int unit, c; register struct tty *tp0; int s; unit = minor(tp->t_dev); tp0 = &qv_tty[(unit&0xfc)+1]; 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 subchannels other * than 0 on the floor. * TANDEM is set on second subchannel for flow control. */ while ( tp->t_outq.c_cc ) { if ((unit & 3) == 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); qvputc( c & 0xff ); } } else if ((unit & 3) == 1) { /* qconsole, do flow control */ c = getc(&tp->t_outq); if ((tp0->t_state&TS_TBLOCK) == 0) { tp = &qv_tty[0]; unit = minor(tp->t_dev); unit &= 0x03; continue; } else goto out; } else c = getc(&tp->t_outq); } /* * Position the cursor to the next character location. */ if (!(qv_dev_inuse & GRAPHIC_DEV)) qv_pos_cur( qv_scn->col*8, qv_scn->row*15 ); if (!(qv_dev_inuse & GRAPHIC_DEV)) qv_pos_cur( qv_scn->col*8, qv_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);}/* * Stop output on a line, e.g. for ^S/^Q or output flush. *//*ARGSUSED*/qvstop(tp, flag) register struct tty *tp;{ register int s; /* * Block input/output interrupts while messing with 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 display a character on the screen. The model used is a * glass tty. It is assummed that the user will only use this emulation * during system boot and that the screen will be eventually controlled * by a window manager. * */qvputc( c )register u_char c;{ register char *b_row, *f_row; register int i; register short *scanline; register int ote = 128; register struct qv_info *qp = qv_scn; register struct qvdevice *qvaddr; struct uba_device *ui; /* * This routine may be called in physical mode by the dump code * so we check and punt if that's the case. */ if( (mfpr(MAPEN) & 1) == 0 ) { ui = qvinfo[0]; qvaddr = (struct qvdevice *)ui->ui_physaddr; if (qv_video_off) { qvaddr->qv_csr |= QV_VIDEO_ENA; /* turn on the video */ qv_video_off = 0; } return; } c &= 0xff; switch ( c ) { case '\t': /* tab */ for( i = 8 - (qp->col & 0x7) ; i > 0 ; i-- ) qvputc( ' ' ); break; case '\r': /* return */ qp->col = 0; break; case '\010': /* backspace */ if( --qp->col < 0 ) qp->col = 0; break; case '\n': /* linefeed */ if( qp->row+1 >= qp->max_row ) qvscroll(); else qp->row++; /* * Position the cursor to the next character location. */ if (!(qv_dev_inuse & GRAPHIC_DEV)) qv_pos_cur( qp->col*8, qp->row*15 ); break; case '\007': /* bell */ /* * We don't do anything to the keyboard until after * autoconfigure. */ if( qp->qvaddr ) qv_key_out( LK_RING_BELL ); return; default: /* * 8-bit support includes the addition of characters A1-FD. */ if(( c >= ' ' && c <= '~' ) || ( c >= 0xA1 && c <= 0xFD)) { scanline = qp->scanmap; b_row = qp->bitmap+(scanline[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);/* for( i=0 ; i<15 ; i++ , b_row += 128, f_row++ ) *b_row = *f_row;*/ /* 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 ) qvscroll(); else qp->row++; } } break; }}/* * QVSS keyboard interrupt. */qvgetc(){ register struct qvdevice *qvaddr; register struct qv_info *qp = qv_scn; char *string; int c; int j; qvaddr = qp->qvaddr; /* * Get a character from the keyboard. */loop: while( (qvaddr->qv_uartstatus & 0x01) == 0 ) ; j = qvaddr->qv_uartdata & 0xff; /* * See if its a state change key */ switch ( j ) { case LOCK: qv_keyboard.lock ^= 0xffff; /* toggle */ if( qv_keyboard.lock ) qv_key_out( LK_LED_ENABLE ); else qv_key_out( LK_LED_DISABLE ); qv_key_out( LED_3 ); goto loop; case SHIFT: qv_keyboard.shift ^= 0xffff; goto loop; case CNTRL: qv_keyboard.cntrl ^= 0xffff; goto loop; case ALLUP: qv_keyboard.cntrl = qv_keyboard.shift = 0; goto loop; case REPEAT: c = qv_keyboard.last; break; default: /* * Test for control characters. If set, see if the character * is elligible to become a control character. */ if( qv_keyboard.cntrl ) { c = q_key[ j ]; if( c >= ' ' && c <= '~' ) c &= 0x1f; } else if( qv_keyboard.lock || qv_keyboard.shift ) c = q_shift_key[ j ]; else c = q_key[ j ]; break; } qv_keyboard.last = c; /* * Check for special function keys */ if( c & 0x80 ) return 0; else return c;}/* * Position the cursor to a particular spot. */qv_pos_cur( x, y)register int x,y;{ register struct qvdevice *qvaddr; register struct qv_info *qp = qv_scn; register index; if( qvaddr = qp->qvaddr ) { if( y < 0 || y > qp->max_cur_y ) y = qp->max_cur_y; if( x < 0 || 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*/ qvaddr->qv_crtaddr = 10; /* select cursor start reg */ qvaddr->qv_crtdata = y & 0xf; qvaddr->qv_crtaddr = 11; /* select cursor end reg */ qvaddr->qv_crtdata = y & 0xf; qvaddr->qv_crtaddr = 14; /* select cursor y pos. */ qvaddr->qv_crtdata = y >> 4; qvaddr->qv_xcur = x; /* pos x axis */ /* * If the mouse is being used then we change the mode of * cursor display based on the pixels under the cursor */ if( mouseon ) { index = y*128 + x/8; if( qp->bitmap[ index ] && qp->bitmap[ index+128 ] ) qvaddr->qv_csr &= ~QV_CUR_MODE; else qvaddr->qv_csr |= QV_CUR_MODE; } }}/* * Scroll the bitmap by moving the scanline map words. This could * be done by moving the bitmap but it's much too slow for a full screen. * The only drawback is that the scanline map must be reset when the user * wants to do graphics. */qvscroll(){ short tmpscanlines[15]; register char *b_row; register short *scanline; register struct qv_info *qp = qv_scn; /* * If the mouse is on we don't scroll so that the bit map * remains sane. */ if( mouseon ) { qp->row = 0; return; } /* * Save the first 15 scanlines so that we can put them at * the bottom when done. */ bcopy( qp->scanmap, tmpscanlines, sizeof tmpscanlines ); /* * Clear the wrapping line so that it won't flash on the bottom * of the screen. */ scanline = qp->scanmap; b_row = qp->bitmap+(*scanline&0x3ff)*128; bzero( b_row, 1920 ); /* * Now move the scanlines down */ bcopy( qp->scanmap+15, qp->scanmap, (qp->row * 15) * sizeof (short) ); /* * Now put the other lines back */ bcopy( tmpscanlines, qp->scanmap+(qp->row * 15), sizeof tmpscanlines );}/* * Output to the keyboard. This routine status polls the transmitter on the * keyboard to output a code. The timer is to avoid hanging on a bad device. */qv_key_out( c )char c;{ int timer = 30000; register struct qv_info *qp = qv_scn; if( qp->qvaddr ) { while( (qp->qvaddr->qv_uartstatus & 0x4) == 0 && timer-- ) ; qp->qvaddr->qv_uartdata = c; }}/* * Virtual console initialization. This routine sets up the qvss 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. * In this case it must map the q-bus and device areas and initialize the qvss * screen. */qvcons_init(){ struct qvdevice *qvaddr; /* device pointer */ short *devptr; /* vitual device space */#define QVSSCSR 017200 /* * Found an entry for this cpu. Because this device is Microvax specific * we assume that there is a single q-bus and don't have to worry about * multiple adapters. * * Map the bus memory and device registers. */ ubaaccess(((*cpup->umaddr)(0)), QMEMmap[0], cpup->pc_umsize, PG_V|PG_KW); ubaaccess(((*cpup->udevaddr)(0)), QMEMmap[0]+btop(cpup->pc_umsize), DEVSPACESIZE ,PG_V|PG_KW); /* * See if the qvss is there. */ devptr = (short *)((char *)qmem[0]+cpup->pc_umsize); qvaddr = (struct qvdevice *)((u_int)devptr + ubdevreg(QVSSCSR)); if( BADADDR( qvaddr, sizeof(short) ) ) return(0); /* * Okay the device is there lets set it up */ qv_setup( qvaddr ); v_consputc = qvputc; v_consgetc = qvgetc; cdevsw[0] = cdevsw[QVSSMAJOR]; ws_display_type = QVSS_DTYPE; /* Identify display as QVSS */ ws_display_units = 1; /* Only unit 0 present */ return(1);}/* * Do the board specific setup */qv_setup( qvaddr )struct qvdevice *qvaddr;{ char *qvssmem; /* pointer to the display mem */ int i; /* simple index */ register struct qv_info *qp; qvssmem = (char *) (( (u_int)(qvaddr->qv_csr & QV_MEM_BANK) <<7 ) + (u_int)qmem[0]); qv_scn = (struct qv_info *) ((u_int)qvssmem + 251*1024); qp = qv_scn; if( (qvaddr->qv_csr & QV_19INCH) && qv_def_scrn == 0) qv_def_scrn = 1; qvinit_scn_def(); *qv_scn = qv_scn_defaults[ qv_def_scrn ]; qp->bitmap = qvssmem; qp->scanmap = (short *)((u_int)qvssmem + 254*1024); qp->cursorbits = (short *)((u_int)qvssmem + 256*1024-32); mouseon = 0; qp->qe.events = (qvEvent *)qp - QVMAXEVQ; qp->qe.eSize = QVMAXEVQ; qp->qe.eHead = qp->qe.eTail = 0; qp->qe.tcs = (qvTimeCoord *)qp->qe.events - MOTION_BUFFER_SIZE; qp->qe.tcSize = MOTION_BUFFER_SIZE; qp->qe.tcNext = 0; /* * Setup the crt controller chip. */ for( i=0 ; i<16 ; i++ ) { qvaddr->qv_crtaddr = i; qvaddr->qv_crtdata = qv_crt_parms[ qv_def_scrn ][ i ]; } /* * Setup the display. */ qv_init( qvaddr ); /* * Turn on the video */ qvaddr->qv_csr |= QV_VIDEO_ENA ;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -