CGJ) AV_FORW
7.2 The Character Interface
7.2.6 EXAMPLES OF CHARACTER 1/0 (TERMINAL) DRIVERS
7.2.6.1 iSBXTM 270 Walkthrough 1/"
2 " i270.c - iSBX270 device driver 3"
AP·184
4 " - implements terminal device driver for the iSBX270 character 5" graphics video display controller
6"
7 • See also: c270.c - i270 configuration 8 " i270.h - i270 include files 9"
10 " Notes on this driver:
11 " (1) The driver supports the keyboard interface and display 12" in scroll mode or page mode
13 * (2)AII manual references in the comments are to the iSBX270 14" Video Display Terminal Controller Board Hardware Reference 15 * Manual, order number 143444-001.
16 *f 17
18 #include " . .lhfparam.h"
19 #include " . .lhfuser.h"
20 #include " . .lhftty.h"
21 #include " . .lhIi270.h"
22
23 extern struct 24
25 short i270-alive;
26 struct tty i270tty;
27 int c..state;
28 291*
30" i270initO
i270cfg i270cfg; 1* configuration structure" f 1* board alive flag" f
1* tty structure * f
f" state variable used for escape sequences * f
31 *. - tests for presence of the iSBX270, and reports its presence 32 * or absence
33 * -initializes 270 for the configured modes of operation 34 * - this routine is called very early in the system initialization 35 *f
36
37 i270initO 38 (
39 short mode;
40 int rststat;
41 421*
43 * The sequence below sends a reset command to the 270. The 44 * algorithm is based on the flowchart, page 3-8 of the manual.
45 * We perform the additional task of determining if the board is 46' present or not.
47 *f 48 c..state 0= 0;
49 rststat
=
rst270(); 1* reset 270 *f 50 if (rststat = = RSTERR)f"
* Board not found.
"f 51 52 53 54 55 56 57 58
printf("iSBX 270 board port %x NOT found.O, i270cfg.c_data);
i270-alive
=
I270DEAD;return;
2-153 280041-001
AP-184
59 } 60 else (
61 printf("iSBX 270 board port %x found.O, i270cfg.c_data);
62 i270_alive = I270LIVES;
63 } 64 651*
66 • Board lives, so set it up in the configuration specified.
67 • NIMASK is anded with everything to clear any bits which 68 • aren't implemented.
69 • Once we reach this point, we'll assume that the board is 70 • alive to some extent, so we'll just concern ourselves w.th 71 * getting through the initialization; but we can't afford to 72 • get hung up if the firmware is acting funny. Our approach 73 * will be to protect ourselves against infinite loops, but not 74 * check for error conditions or worry about reporting them.
75 *1 76
77 mode = (i270cfg.c_keybrd
I
i270cfg.clpenI
i270cfg.cdmaI
78 i270cfg.cmode
I
IBEINTI
(i270cfg.c_cursor & CURMSK)) 79 &NIMASK;80 mode270(mode);
81 } 82 831*
84 • rst2700 - resets the 270 board 85 *1
86 87 rst2700 88 (
89 unsigned i;
90 91/*
92 * Clear out any garbage in input and output buffers.
93 * i is a safety valve in case the board is not here and 94 * we read a 1 in the IBF bit - we'll take care of the 95 • presence or absence of the board later - for now we just 96 * need to get out of this loop.
97 *1 98 99i = 0;
100 while «in-270(i270cfg.cstat) & I270IBF) &&
0+ +
< 30000)) ( 101 if (in_270(i270cfg.c_stat) & I2700BF)102 in_270(i270cfg.cdata); 1* dummy data *1 103 }
104 ouL270(i270cfg.cstat, I270RST); 1* reset it *1 105
1061*
107 * We'll look for some sign oflife from the 270. If 108 • it's not there, we'll either blow right through the 109 • loop, or get stuck in it forever. We'll limit
110 * forever to 30000 iterations, and check for a count of 111 * 0 or
>
30000 upon terminating the loop - either one is 112 • then interpreted as a sign that the board isn't here.113 *1 114 115 i = O·
116 while' «in-270(i270cfg.c_stat) &
117 (I2700BF
I
I270IBFI
I270BUS)) && (j+ + <
30000)) ( 118 if (in_270(i270cfg.cstat) & 12700BF)2-154 280041-001
AP-184
119 in-270(i270cfg.c--"ata); 1* dummy input */
120 }
121 if((i
= =
0)I
(i>
30000» return RSTERR;122 else return RSTOK;
123}
124 125/*
126 * mode270(mode) - sets VOTC mode for 270 board to specified mode 127 */
128
129 mode270(mode) 130 short mode;
13l{
132 unsigned i;
133 134/*
135 * First, go into null busy wait until we can stick another 136 • command into the input buffer - once again, i is used as 137 * an escape in case the firmware on the 270 is acting goofy.
138 *f 139 i = O'
140 while' ((in_270(i270cfg.c...stat) & I270IBF) && (i+ +
<
30000»;141 1421*
143 * Now we can issue a new command - we do a set VOTC mode.
144 *f 145
146 ouL270(i270cfg.c...stat, I270SM);
147 1481*
149 * Wait until the 270 can accept the parameter.
150 *f 151 152 i = O'
153 while' (((in-270(i270cfg.c_stat) &
154 (I2700BF II270IBF II270BUS» ! = I270BUS) && (i+ +
<
30000» ( 155 if (in-270(i270cfg.c...stat) & I2700BF)156 in-270(i270cfg.c_data); 1* dummy input ifOBF set *f 157}
158 ouL270(i270cfg.c_data, mode);
159}
160 1611*
162 * i270open(dev) - opens dev 163 *f
164 '
165i270open(dev) 166 dev_t dey;
167 (
168 int unit, i270startO;
169 struct tty *tp;
170 1711*
172 • First check to make sure that board is alive - if not, 173 * mark error and return.
174 *f 175
176 if (i270....alive
==
I270DEAO) {177 u. u_error = ENXIO; 1* no such device or address * f 178 return;
2-155 280041-001
179 } 180 1811*
182 ° tp will point to the tty structure 183 *f
184
185 tp = &i270tty;
186 1871*
AP-184
188 ° Check for 270 already being exclusively opened 189 of
190
191 if «tp->Lstate & XCLUDE) && u.u_uid) { 192 u.u_error = EBUSY;
193 return;
194 } 195 1961*
197 ° Set up fields in tty structure.
198
*'
199
200 tp->Laddr = (caddr_t)i270cfg.c_data;
r
io base address*'
201 tp- > Loproc = i270start; 1* routine to start output
*'
202 203
,*
204 * If this is first open ...
205
*'
206
207 if «tp- > Lstate & ISOPEN) = = 0) {
208, ttychars(tp);
r
sets special characters0,
209 tp-> Lispeed = tp->Lospeed = 9600; 1* baud rate meaningless
0,
210 tp- > Lflags = ODDP 1 EVENP 1 ECHO 1 CRMOD; 1* should add no
211 tab expansion here
*'
212 }
213 tp->Lstate
1=
CARR_ON;214 ttyopen(dev, tp);
215 } 216 2171*
218 * i270close(dev, flag) 219
0,
220
221 i270close(dev) 222 dev_t dey;
223 (
224 struct tty °tp;
225
226 tp = &i270tty;
227 ttyclose(tp);
228 tp- >Laddr = (caddr _t) 0; 1* forget base address * , 229 }
230
231i270read(dev) 232 dev_t dey;
233 (
234 struct tty °tp;
235
236 tp = &i270tty;
237 ttread(tp);
238}
2-156 280041-001
inter
239
240 i270write (dev) 241 dev_t dey;
242 (
243 struct tty *tp;
244
245 tp = &i270tty;
246 ttwrite(tp);
247 ) 248
249 i270iintr(JeveI) 250 int level;
251 (
252 struct tty *tp;
253 short status, chr;
254
255 tp = &i270tty;
256 status = inb(i270cfg.c-stat);
257 chr = inb(i270cfg.cdata);
258 if (status & I270KDR)
AP-184
259 ttyinput(chr, tp); 1* only if a valid keyboard hit *f 260 )
261
262 i270ointr(JeveI) 263 int level;
264 ( 265 struct 266
tty 267 tp = &i270tty;
*tp;
268 if (tp- > Lstate & BUSY) ( 269 tp- > Lstate & = - BUSY;
270 ttstart(tp);
271 if «tp-> Lstate & ASLEEP) &&
272 (tp-> Loutq.c_cc
<
= TTLOWAT»273 wakeup«caddLt)&tp-> Loutq);
274 ) 275 }
276 int ttrstrtO;
277 extern char par tab [];
278
279 i270start(tp) 280 struc( tty *tp;
281 ( 282 int e,s;
283 short mode;
284 285 286 287 288
s = sp150;
if (tp-> Lstate & (TIMEOUT IBUSY» ( splx(s);
return;
289 }
290 if «c=getc(&tp->Loutq» >= 0) ( 291 tp->Lstatel= BUSY;
292 splx (s);
293 switch (c-state) ( 294 case 0:
295' if(c==Oxlb)(
296 #ifdefDEBUG 297
298 #endif
printf("O %xO, c);
2-157 280041-001
inter
timeout(ttrstrt, (caddU}tp, (c & Ox7f»;
return;
break;
case 1:
switch (c) case '=':
1* cursor address sequence
*'
319 #ifdefDEBUG
1* visual attribute sequence "' printf("O 00000);
335 outb(i270cfg.c_data, 0);
336 c-state = 6;
352 outb(i270cfg.c-stat, I270SCP);
353 c_state = 4;
inter
AP-184outb(i270cfg.c_data, «c & Ox30
I
Ox80»;c_state = 0;
break;
case 4:
outb(i270cfg.c_data, (c - Ox30»;
c-state = 5;
break;
case 5:
outb(i270cfg.c_data, (c - Ox30»;
c-state = 0;
i270cfg,cdma
I
i270cfgLmodeI
378
IBEINT
I
(i270cfg.c_cursor & CURMSK»&NIMASK;
* just output character and go back to state 0
-* nothing special, just didn't want to flip into a
* special mode as a result of this graphics character
*f
397 i270ioctl(dev, cmd, addr, flag) 398 caddLt addr;
* No ioctl functions supported
*f
409 else u.u_error = ENOTTY;
410
I
411
412in-270(port) 413 unsigned port;
414 (
415 unsigned i;
416
417( for (i=0; i
<
DELAY270; i+ +);418 return (short) inb(port);
2-159 280041-001
AP-184