* Copyright (c) 1992 Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* %sccs.include.redist.c%
* @(#)dc.c 7.2 (Berkeley) %G%
* This file contains machine-dependent routines that handle the
* output queue for the serial lines.
* Copyright (C) 1989 Digital Equipment Corporation.
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies.
* Digital Equipment Corporation makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
* from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devDC7085.c,
* v 1.4 89/08/29 11:55:30 nelson Exp $ SPRITE (DECWRL)";
* DC7085 (DZ-11 look alike) Driver
#include "machine/dc7085cons.h"
* Driver information for auto-configuration stuff.
struct driver dcdriver
= {
extern int dcstart(), dcxint();
struct tty dc_tty
[NDCLINE
];
int dcDivertXInput
; /* true if diverting KBD input to X */
* Software copy of brk register since it isn't readable
char dcsoftCAR
[NDC
]; /* mask of dc's with carrier on (DSR) */
* The DC7085 doesn't interrupt on carrier transitions, so
* we have to use a timer to watch it.
int dc_timer
; /* true if timer started */
* Pdma structures for fast output code
struct pdma dcpdma
[NDCLINE
];
struct speedtab dcspeedtab
[] = {
#define ISPEED TTYDEF_SPEED
#define LFLAG TTYDEF_LFLAG
#define LFLAG (TTYDEF_LFLAG & ~ECHO)
* Ascii values of command keys.
* Define "hardware-independent" codes for the control, shift, meta and
* function keys. Codes start after the last 7-bit ASCII code (127)
* and are assigned in an arbitrary order.
#define KBD_ALTERNATE 239
* Keyboard to Ascii, unshifted.
static unsigned char unshiftedAscii
[] = {
/* 0 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 4 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 8 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 10 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 14 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 18 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 1c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 20 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 24 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 28 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 2c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 30 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 34 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 38 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 3c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 40 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 44 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 48 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 4c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 50 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 54 */ KBD_NOKEY
, KBD_NOKEY
, KBD_F1
, KBD_F2
,
/* 58 */ KBD_F3
, KBD_F4
, KBD_F5
, KBD_NOKEY
,
/* 5c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 60 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 64 */ KBD_F6
, KBD_F7
, KBD_F8
, KBD_F9
,
/* 68 */ KBD_F10
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 6c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 70 */ KBD_NOKEY
, '\033', KBD_F12
, KBD_F13
,
/* 74 */ KBD_F14
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 78 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 7c */ KBD_HELP
, KBD_DO
, KBD_NOKEY
, KBD_NOKEY
,
/* 80 */ KBD_F17
, KBD_F18
, KBD_F19
, KBD_F20
,
/* 84 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 88 */ KBD_NOKEY
, KBD_NOKEY
, KBD_FIND
, KBD_INSERT
,
/* 8c */ KBD_REMOVE
, KBD_SELECT
, KBD_PREVIOUS
, KBD_NEXT
,
/* 90 */ KBD_NOKEY
, KBD_NOKEY
, '0', KBD_NOKEY
,
/* 94 */ '.', KBD_KP_ENTER
, '1', '2',
/* 98 */ '3', '4', '5', '6',
/* 9c */ ',', '7', '8', '9',
/* a0 */ '-', KBD_KP_F1
, KBD_KP_F2
, KBD_KP_F3
,
/* a4 */ KBD_KP_F4
, KBD_NOKEY
, KBD_NOKEY
, KBD_LEFT
,
/* a8 */ KBD_RIGHT
, KBD_DOWN
, KBD_UP
, KBD_NOKEY
,
/* ac */ KBD_NOKEY
, KBD_NOKEY
, KBD_SHIFT
, KBD_CONTROL
,
/* b0 */ KBD_CAPSLOCK
, KBD_ALTERNATE
, KBD_NOKEY
, KBD_NOKEY
,
/* b4 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* b8 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* bc */ KBD_DEL
, KBD_RET
, KBD_TAB
, '`',
/* c0 */ '1', 'q', 'a', 'z',
/* c4 */ KBD_NOKEY
, '2', 'w', 's',
/* c8 */ 'x', '<', KBD_NOKEY
, '3',
/* cc */ 'e', 'd', 'c', KBD_NOKEY
,
/* d0 */ '4', 'r', 'f', 'v',
/* d4 */ ' ', KBD_NOKEY
, '5', 't',
/* d8 */ 'g', 'b', KBD_NOKEY
, '6',
/* dc */ 'y', 'h', 'n', KBD_NOKEY
,
/* e0 */ '7', 'u', 'j', 'm',
/* e4 */ KBD_NOKEY
, '8', 'i', 'k',
/* e8 */ ',', KBD_NOKEY
, '9', 'o',
/* ec */ 'l', '.', KBD_NOKEY
, '0',
/* f0 */ 'p', KBD_NOKEY
, ';', '/',
/* f4 */ KBD_NOKEY
, '=', ']', '\\',
/* f8 */ KBD_NOKEY
, '-', '[', '\'',
/* fc */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
* Keyboard to Ascii, shifted.
static unsigned char shiftedAscii
[] = {
/* 0 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 4 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 8 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 10 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 14 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 18 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 1c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 20 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 24 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 28 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 2c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 30 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 34 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 38 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 3c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 40 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 44 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 48 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 4c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 50 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 54 */ KBD_NOKEY
, KBD_NOKEY
, KBD_F1
, KBD_F2
,
/* 58 */ KBD_F3
, KBD_F4
, KBD_F5
, KBD_NOKEY
,
/* 5c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 60 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 64 */ KBD_F6
, KBD_F7
, KBD_F8
, KBD_F9
,
/* 68 */ KBD_F10
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 6c */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 70 */ KBD_NOKEY
, KBD_F11
, KBD_F12
, KBD_F13
,
/* 74 */ KBD_F14
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 78 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 7c */ KBD_HELP
, KBD_DO
, KBD_NOKEY
, KBD_NOKEY
,
/* 80 */ KBD_F17
, KBD_F18
, KBD_F19
, KBD_F20
,
/* 84 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* 88 */ KBD_NOKEY
, KBD_NOKEY
, KBD_FIND
, KBD_INSERT
,
/* 8c */ KBD_REMOVE
, KBD_SELECT
, KBD_PREVIOUS
, KBD_NEXT
,
/* 90 */ KBD_NOKEY
, KBD_NOKEY
, '0', KBD_NOKEY
,
/* 94 */ '.', KBD_KP_ENTER
, '1', '2',
/* 98 */ '3', '4', '5', '6',
/* 9c */ ',', '7', '8', '9',
/* a0 */ '-', KBD_KP_F1
, KBD_KP_F2
, KBD_KP_F3
,
/* a4 */ KBD_KP_F4
, KBD_NOKEY
, KBD_NOKEY
, KBD_LEFT
,
/* a8 */ KBD_RIGHT
, KBD_DOWN
, KBD_UP
, KBD_NOKEY
,
/* ac */ KBD_NOKEY
, KBD_NOKEY
, KBD_SHIFT
, KBD_CONTROL
,
/* b0 */ KBD_CAPSLOCK
, KBD_ALTERNATE
, KBD_NOKEY
, KBD_NOKEY
,
/* b4 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* b8 */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
/* bc */ KBD_DEL
, KBD_RET
, KBD_TAB
, '~',
/* c0 */ '!', 'q', 'a', 'z',
/* c4 */ KBD_NOKEY
, '@', 'w', 's',
/* c8 */ 'x', '>', KBD_NOKEY
, '#',
/* cc */ 'e', 'd', 'c', KBD_NOKEY
,
/* d0 */ '$', 'r', 'f', 'v',
/* d4 */ ' ', KBD_NOKEY
, '%', 't',
/* d8 */ 'g', 'b', KBD_NOKEY
, '^',
/* dc */ 'y', 'h', 'n', KBD_NOKEY
,
/* e0 */ '&', 'u', 'j', 'm',
/* e4 */ KBD_NOKEY
, '*', 'i', 'k',
/* e8 */ '<', KBD_NOKEY
, '(', 'o',
/* ec */ 'l', '>', KBD_NOKEY
, ')',
/* f0 */ 'p', KBD_NOKEY
, ':', '?',
/* f4 */ KBD_NOKEY
, '+', '}', '|',
/* f8 */ KBD_NOKEY
, '_', '{', '"',
/* fc */ KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
, KBD_NOKEY
,
* Keyboard initialization string.
static u_char kbdInitString
[] = {
LK_LED_ENABLE
, LED_ALL
, /* show we are resetting keyboard */
LK_CMD_MODE(LK_AUTODOWN
, 1),
LK_CMD_MODE(LK_AUTODOWN
, 2),
LK_CMD_MODE(LK_AUTODOWN
, 3),
LK_CMD_MODE(LK_DOWN
, 4), /* could also be LK_AUTODOWN */
LK_CMD_MODE(LK_UPDOWN
, 5),
LK_CMD_MODE(LK_UPDOWN
, 6),
LK_CMD_MODE(LK_AUTODOWN
, 7),
LK_CMD_MODE(LK_AUTODOWN
, 8),
LK_CMD_MODE(LK_AUTODOWN
, 9),
LK_CMD_MODE(LK_AUTODOWN
, 10),
LK_CMD_MODE(LK_AUTODOWN
, 11),
LK_CMD_MODE(LK_AUTODOWN
, 12),
LK_CMD_MODE(LK_DOWN
, 13),
LK_CMD_MODE(LK_AUTODOWN
, 14),
LK_AR_ENABLE
, /* we want autorepeat by default */
LK_CL_ENABLE
, 0x83, /* keyclick, volume */
LK_KBD_ENABLE
, /* the keyboard itself */
LK_BELL_ENABLE
, 0x83, /* keyboard bell, volume */
LK_LED_DISABLE
, LED_ALL
, /* clear keyboard leds */
* Test to see if device is present.
* Return true if found and initialized ok.
register struct pmax_ctlr
*cp
;
register struct pdma
*pdp
;
extern void dcKBDReset();
if (cp
->pmax_unit
>= NDC
)
if (badaddr(cp
->pmax_addr
, 2))
dcaddr
= (dcregs
*)cp
->pmax_addr
;
dcaddr
->dc_csr
= CSR_CLR
;
while (dcaddr
->dc_csr
& CSR_CLR
)
dcaddr
->dc_csr
= CSR_MSE
| CSR_TIE
| CSR_RIE
;
/* init pseudo DMA structures */
pdp
= &dcpdma
[cp
->pmax_unit
* 4];
tp
= &dc_tty
[cp
->pmax_unit
* 4];
for (cntr
= 0; cntr
< 4; cntr
++) {
tp
->t_addr
= (caddr_t
)pdp
;
dcsoftCAR
[cp
->pmax_unit
] = cp
->pmax_flags
| 0xB;
timeout(dcscan
, (caddr_t
)0, hz
);
printf("dc%d at nexus0 csr 0x%x\n", cp
->pmax_unit
, cp
->pmax_addr
);
if (cp
->pmax_unit
== 0) {
dcaddr
->dc_lpr
= LPR_RXENAB
| LPR_B4800
| LPR_8_BIT_CHAR
|
dcaddr
->dc_lpr
= LPR_RXENAB
| LPR_B4800
| LPR_OPAR
|
LPR_PARENB
| LPR_8_BIT_CHAR
| MOUSE_PORT
;
if (unit
>= dc_cnt
|| dcpdma
[unit
].p_addr
== 0)
tp
->t_addr
= (caddr_t
)&dcpdma
[unit
];
if ((tp
->t_state
& TS_ISOPEN
) == 0) {
tp
->t_iflag
= TTYDEF_IFLAG
;
tp
->t_oflag
= TTYDEF_OFLAG
;
tp
->t_cflag
= TTYDEF_CFLAG
;
tp
->t_ispeed
= tp
->t_ospeed
= ISPEED
;
(void) dcparam(tp
, &tp
->t_termios
);
} else if ((tp
->t_state
& TS_XCLUDE
) && curproc
->p_ucred
->cr_uid
!= 0)
(void) dcmctl(dev
, DML_DTR
, DMSET
);
while (!(flag
& O_NONBLOCK
) && !(tp
->t_cflag
& CLOCAL
) &&
!(tp
->t_state
& TS_CARR_ON
)) {
if (error
= ttysleep(tp
, (caddr_t
)&tp
->t_rawq
, TTIPRI
| PCATCH
,
return ((*linesw
[tp
->t_line
].l_open
)(dev
, tp
));
bit
= 1 << ((unit
& 03) + 8);
if (dc_brk
[unit
>> 2] & bit
) {
dc_brk
[unit
>> 2] &= ~bit
;
(*linesw
[tp
->t_line
].l_close
)(tp
);
if ((tp
->t_cflag
& HUPCL
) || (tp
->t_state
& TS_WOPEN
) ||
!(tp
->t_state
& TS_ISOPEN
))
(void) dcmctl(dev
, 0, DMSET
);
tp
= &dc_tty
[minor(dev
)];
return ((*linesw
[tp
->t_line
].l_read
)(tp
, uio
, flag
));
tp
= &dc_tty
[minor(dev
)];
return ((*linesw
[tp
->t_line
].l_write
)(tp
, uio
, flag
));
* Check for interrupts from all devices.
for (unit
= 0, p
= dcpdma
; p
< &dcpdma
[NDCLINE
]; unit
+= 4, p
+= 4) {
while ((csr
= p
->p_addr
->dc_csr
) & (CSR_RDONE
| CSR_TRDY
)) {
dcxint(&dc_tty
[unit
+ ((csr
>> 8) & 03)]);
register struct tty
*tp0
;
dcaddr
= dcpdma
[unit
].p_addr
;
while ((c
= dcaddr
->dc_rbuf
) < 0) { /* char present */
tp
= tp0
+ ((c
>> 8) & 03);
if ((c
& RBUF_OERR
) && overrun
== 0) {
log(LOG_WARNING
, "dc%d,%d: silo overflow\n", unit
>> 2,
/* the keyboard requires special translation */
if (tp
== &dc_tty
[KBD_PORT
]) {
"dc0,0: keyboard error, code=%x\n", cc
);
* A function key was typed - ignore it.
if (cc
>= 'a' && cc
<= 'z') {
cc
= cc
- 'a' + '\1'; /* ^A */
if (cc
>= '[' && cc
<= '_')
else if (cc
== ' ' || cc
== '@')
} else if (tp
== &dc_tty
[MOUSE_PORT
]) {
register MouseReport
*newRepPtr
;
static MouseReport currentRep
;
if (cc
& MOUSE_START_FRAME
) {
* The first mouse report byte (button state).
if (newRepPtr
->byteCount
> 1)
newRepPtr
->byteCount
= 1;
} else if (newRepPtr
->byteCount
== 2) {
* The second mouse report byte (delta x).
} else if (newRepPtr
->byteCount
== 3) {
* The final mouse report byte (delta y).
newRepPtr
->byteCount
= 0;
if (newRepPtr
->dx
!= 0 || newRepPtr
->dy
!= 0) {
pmMouseButtons(newRepPtr
);
if (!(tp
->t_state
& TS_ISOPEN
)) {
wakeup((caddr_t
)&tp
->t_rawq
);
if (!(tp
->t_state
& TS_WOPEN
))
(*linesw
[tp
->t_line
].l_rint
)(cc
, tp
);
dcioctl(dev
, cmd
, data
, flag
)
register int unit
= minor(dev
);
register int dc
= unit
>> 2;
error
= (*linesw
[tp
->t_line
].l_ioctl
)(tp
, cmd
, data
, flag
);
error
= ttioctl(tp
, cmd
, data
, flag
);
dc_brk
[dc
] |= 1 << ((unit
& 03) + 8);
dc_brk
[dc
] &= ~(1 << ((unit
& 03) + 8));
(void) dcmctl(dev
, DML_DTR
|DML_RTS
, DMBIS
);
(void) dcmctl(dev
, DML_DTR
|DML_RTS
, DMBIC
);
(void) dcmctl(dev
, *(int *)data
, DMSET
);
(void) dcmctl(dev
, *(int *)data
, DMBIS
);
(void) dcmctl(dev
, *(int *)data
, DMBIC
);
*(int *)data
= dcmctl(dev
, 0, DMGET
);
register struct termios
*t
;
register int cflag
= t
->c_cflag
;
int unit
= minor(tp
->t_dev
);
int ospeed
= ttspeedtab(t
->c_ospeed
, dcspeedtab
);
/* check requested parameters */
if (ospeed
< 0 || (t
->c_ispeed
&& t
->c_ispeed
!= t
->c_ospeed
) ||
(cflag
& CSIZE
) == CS5
|| (cflag
& CSIZE
) == CS6
)
tp
->t_ispeed
= t
->c_ispeed
;
tp
->t_ospeed
= t
->c_ospeed
;
dcaddr
= dcpdma
[unit
].p_addr
;
if (tp
== dc_tty
+ KBD_PORT
) {
/* handle the keyboard specially */
dcaddr
->dc_lpr
= LPR_RXENAB
| LPR_B4800
| LPR_8_BIT_CHAR
|
if (tp
== dc_tty
+ MOUSE_PORT
) {
/* handle the mouse specially */
dcaddr
->dc_lpr
= LPR_RXENAB
| LPR_B4800
| LPR_OPAR
|
LPR_PARENB
| LPR_8_BIT_CHAR
| MOUSE_PORT
;
(void) dcmctl(unit
, 0, DMSET
); /* hang up line */
lpr
= LPR_RXENAB
| ospeed
| (unit
& 03);
if ((cflag
& CSIZE
) == CS7
)
register struct pdma
*dp
;
dp
= (struct pdma
*)tp
->t_addr
;
if (dp
->p_mem
< dp
->p_end
) {
dcaddr
->dc_tdr
= dc_brk
[(tp
- dc_tty
) >> 2] | *dp
->p_mem
++;
if (tp
->t_state
& TS_FLUSH
)
tp
->t_state
&= ~TS_FLUSH
;
ndflush(&tp
->t_outq
, dp
->p_mem
-tp
->t_outq
.c_cf
);
dp
->p_end
= dp
->p_mem
= tp
->t_outq
.c_cf
;
(*linesw
[tp
->t_line
].l_start
)(tp
);
if (tp
->t_outq
.c_cc
== 0 || !(tp
->t_state
& TS_BUSY
)) {
dp
->p_addr
->dc_tcr
&= ~(1 << (minor(tp
->t_dev
) & 03));
register struct pdma
*dp
;
dp
= (struct pdma
*)tp
->t_addr
;
if (tp
->t_state
& (TS_TIMEOUT
|TS_BUSY
|TS_TTSTOP
))
if (tp
->t_outq
.c_cc
<= tp
->t_lowat
) {
if (tp
->t_state
& TS_ASLEEP
) {
tp
->t_state
&= ~TS_ASLEEP
;
wakeup((caddr_t
)&tp
->t_outq
);
if (tp
->t_outq
.c_cc
== 0)
/* handle console specially */
while (tp
->t_outq
.c_cc
> 0) {
cc
= getc(&tp
->t_outq
) & 0x7f;
* After we flush the output queue we may need to wake
* up the process that made the output.
if (tp
->t_outq
.c_cc
<= tp
->t_lowat
) {
if (tp
->t_state
& TS_ASLEEP
) {
tp
->t_state
&= ~TS_ASLEEP
;
wakeup((caddr_t
)&tp
->t_outq
);
if (tp
->t_flags
& (RAW
|LITOUT
))
cc
= ndqb(&tp
->t_outq
, 0);
cc
= ndqb(&tp
->t_outq
, 0200);
timeout(ttrstrt
, (caddr_t
)tp
, (cc
& 0x7f) + 6);
tp
->t_state
|= TS_TIMEOUT
;
dp
->p_end
= dp
->p_mem
= tp
->t_outq
.c_cf
;
dcaddr
->dc_tcr
|= 1 << (minor(tp
->t_dev
) & 03);
register struct pdma
*dp
;
dp
= (struct pdma
*)tp
->t_addr
;
if (tp
->t_state
& TS_BUSY
) {
if (!(tp
->t_state
& TS_TTSTOP
))
register int unit
, mbits
;
dcaddr
= dcpdma
[unit
].p_addr
;
/* only channel 2 has modem control (what about line 3?) */
if (dcaddr
->dc_tcr
& TCR_DTR2
)
if (dcaddr
->dc_msr
& MSR_DSR2
)
mbits
|= DML_DSR
| DML_CAR
;
mbits
= DML_DTR
| DML_DSR
| DML_CAR
;
dcaddr
->dc_tcr
|= TCR_DTR2
;
dcaddr
->dc_tcr
&= ~TCR_DTR2
;
if ((mbits
& DML_DTR
) && (dcsoftCAR
[unit
>> 2] & b
))
dc_tty
[unit
].t_state
|= TS_CARR_ON
;
* This is called by timeout() periodically.
* Check to see if modem status bits have changed.
register int i
, bit
, car
;
/* only channel 2 has modem control (what about line 3?) */
dcaddr
= dcpdma
[i
= 2].p_addr
;
if (dcsoftCAR
[i
>> 2] & bit
)
car
= dcaddr
->dc_msr
& MSR_DSR2
;
if (!(tp
->t_state
& TS_CARR_ON
))
(void)(*linesw
[tp
->t_line
].l_modem
)(tp
, 1);
} else if ((tp
->t_state
& TS_CARR_ON
) &&
(*linesw
[tp
->t_line
].l_modem
)(tp
, 0) == 0)
timeout(dcscan
, (caddr_t
)0, hz
);
* ----------------------------------------------------------------------------
* Put a character out to the keyboard.
* A character is written to the keyboard.
* ----------------------------------------------------------------------------
dcaddr
= dcpdma
[KBD_PORT
].p_addr
;
dcaddr
->dc_tcr
= tcr
| (1 << KBD_PORT
);
* Wait for transmitter to be not busy.
while (!(dcaddr
->dc_csr
& CSR_TRDY
) && timeout
> 0)
printf("dcKBDPutc: timeout waiting for CSR_TRDY\n");
line
= (dcaddr
->dc_csr
>> 8) & 3;
* Check to be sure its the right port.
dcaddr
->dc_tcr
&= ~(1 << line
);
* Start sending the character.
dcaddr
->dc_tdr
= dc_brk
[0] | (c
& 0xff);
* Wait for character to be sent.
* cc -O bug: this code produces and infinite loop!
* while (!(dcaddr->dc_csr & CSR_TRDY))
while (!(dcaddr
->dc_csr
& CSR_TRDY
) && timeout
> 0)
line
= (dcaddr
->dc_csr
>> 8) & 3;
dcaddr
->dc_tcr
&= ~(1 << line
);
dcaddr
->dc_tcr
&= ~(1 << KBD_PORT
);
* Enable interrupts for other lines which became ready.
* ----------------------------------------------------------------------------
* Read a character from the keyboard.
* A character read from the mouse, -1 if none were ready.
* ----------------------------------------------------------------------------
dcaddr
= dcpdma
[KBD_PORT
].p_addr
;
while (dcaddr
->dc_csr
& CSR_RDONE
) {
if (((c
>> 8) & 03) == KBD_PORT
)
* ----------------------------------------------------------------------------
* Reset the keyboard to default characteristics.
* ----------------------------------------------------------------------------
for (i
= 0; i
< sizeof(kbdInitString
); i
++)
dcKBDPutc((int)kbdInitString
[i
]);
* ----------------------------------------------------------------------------
* Write a character to the mouse.
* This is only called at initialization time.
* A character is written to the mouse.
* ----------------------------------------------------------------------------
dcaddr
= dcpdma
[MOUSE_PORT
].p_addr
;
dcaddr
->dc_tcr
= tcr
| (1 << MOUSE_PORT
);
* Wait for transmitter to be not busy.
while (!(dcaddr
->dc_csr
& CSR_TRDY
) && timeout
> 0)
printf("MousePutc: timeout waiting for CSR_TRDY\n");
line
= (dcaddr
->dc_csr
>> 8) & 3;
* Check to be sure its the right port.
if (line
!= MOUSE_PORT
) {
dcaddr
->dc_tcr
&= ~(1 << line
);
* Start sending the character.
dcaddr
->dc_tdr
= dc_brk
[0] | (c
& 0xff);
* Wait for character to be sent.
* cc -O bug: this code produces and infinite loop!
* while (!(dcaddr->dc_csr & CSR_TRDY))
while (!(dcaddr
->dc_csr
& CSR_TRDY
) && timeout
> 0)
line
= (dcaddr
->dc_csr
>> 8) & 3;
if (line
!= MOUSE_PORT
) {
dcaddr
->dc_tcr
&= ~(1 << line
);
dcaddr
->dc_tcr
&= ~(1 << MOUSE_PORT
);
* Enable interrupts for other lines which became ready.
* ----------------------------------------------------------------------------
* Read a character from the mouse.
* This is only called at initialization time.
* A character read from the mouse, -1 if we timed out waiting.
* ----------------------------------------------------------------------------
dcaddr
= dcpdma
[MOUSE_PORT
].p_addr
;
for (timeout
= 1000000; timeout
> 0; timeout
--) {
if (!(dcaddr
->dc_csr
& CSR_RDONE
))
if (((c
>> 8) & 03) != MOUSE_PORT
)
* ----------------------------------------------------------------------------
* ----------------------------------------------------------------------------
int id_byte1
, id_byte2
, id_byte3
, id_byte4
;
MousePutc(MOUSE_SELF_TEST
);
printf("MouseInit: Timeout on 1st byte of self-test report\n");
printf("MouseInit: Timeout on 2nd byte of self-test report\n");
printf("MouseInit: Timeout on 3rd byte of self-test report\n");
printf("MouseInit: Timeout on 4th byte of self-test report\n");
if ((id_byte2
& 0x0f) != 0x2)
printf("MouseInit: We don't have a mouse!!!\n");
* For some reason, the mouse doesn't see this command if it comes
* too soon after a self test.
MousePutc(MOUSE_INCREMENTAL
);