~kris/9p

9hist

ref: 9dddf4b3142fc2e2ae683e1cb7c0f2b503ef96ed 9hist/ss/uart.c -rw-r--r-- 2.1 KiB
9dddf4b3 — David du Colombier Plan 9 from Bell Labs 1990-12-27 35 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"

enum
{
	/* wr 0 */
	ResExtPend=	2<<3,
	ResTxPend=	5<<3,
	ResErr=		6<<3,

	/* wr 1 */
	TxIntEna=	1<<1,
	RxIntDis=	0<<3,
	RxIntFirstEna=	1<<3,
	RxIntAllEna=	2<<3,

	/* wr 3 */
	RxEna=		1,
	Rx5bits=	0<<6,
	Rx7bits=	1<<6,
	Rx6bits=	2<<6,
	Rx8bits=	3<<6,

	/* wr 4 */
	SyncMode=	0<<2,
	Rx1stop=	1<<2,
	Rx1hstop=	2<<2,
	Rx2stop=	3<<2,
	X16=		1<<6,

	/* wr 5 */
	TxRTS=		1<<1,
	TxEna=		1<<3,
	TxBreak=	1<<4,
	TxDTR=		1<<7,
	Tx5bits=	0<<5,
	Tx7bits=	1<<5,
	Tx6bits=	2<<5,
	Tx8bits=	3<<5,

	/* wr 9 */
	IntEna=		1<<3,
	ResetB=		1<<6,
	ResetA=		2<<6,
	HardReset=	3<<6,

	/* wr 11 */
	TRxCOutBR=	2,
	TxClockBR=	2<<3,
	RxClockBR=	2<<5,
	TRxCOI=		1<<2,

	/* wr 14 */
	BREna=		1,
	BRSource=	2,

	/* rr 0 */
	RxReady=	1,
	TxReady=	1<<2,
	RxDCD=		1<<3,
	RxCTS=		1<<5,
	RxBreak=	1<<7,

	/* rr 3 */
	ExtPendB=	1,	
	TxPendB=	1<<1,
	RxPendB=	1<<2,
	ExtPendA=	1<<3,	
	TxPendA=	1<<4,
	RxPendA=	1<<5,
};

typedef struct SCC	SCC;
struct SCC
{
	uchar	*ptr;		/* command/pointer register in Z8530 */
	uchar	*data;		/* data register in Z8530 */
};
SCC	scc[2];
#define	SCCV	(0x0000)	/* was 0x0F000000-0x1000 */
#define	SCCP	0xF1000000

#define PRINTING	0x4
#define MASK		0x1

void
sccsetup(void)
{
	ulong pte;

	pte = 	PTEVALID |
		PTEWRITE |
		PTEKERNEL |
		PTENOCACHE |
		PTEIO |
		((SCCP>>PGSHIFT)&0xFFFF)
		;
	putpmeg(SCCV, pte);
	scc[0].ptr = (uchar*)(SCCV+0);
	scc[0].data = (uchar*)(SCCV+2);
	scc[1].ptr = (uchar*)(SCCV+4);
	scc[1].data = (uchar*)(SCCV+6);
}

/*
 *  Access registers using the pointer in register 0.
 *  This is a bit stupid when accessing register 0.
 */
void
sccwrreg(SCC *sp, int addr, int value)
{
	*sp->ptr = addr;
}

ushort
sccrdreg(SCC *sp, int addr)
{
	*sp->ptr = addr;
	return *sp->ptr;
}


/*
 *  non-spooling non-interrupting get and put
 */
int
sccgetc(void)
{
	uchar ch;
	SCC *sp;

	sp = &scc[1];
	while((*sp->ptr&RxReady) == 0)
		;
	return *sp->data;
}
void
sccputc(int ch)
{
	SCC *sp;

	sp = &scc[1];
	while((*sp->ptr&TxReady)==0)
		;
	*sp->data = ch;
}
void
sccputs(char *s)
{
	while(*s)
		sccputc(*s++);
}