|
|
1.1 root 1: /* (-lgl
2: * COHERENT Driver Kit Version 1.1.0
3: * Copyright (c) 1982, 1990 by Mark Williams Company.
4: * All rights reserved. May not be copied without permission.
5: -lgl) */
6: /*
7: * Memory Mapped Video
8: * High level output routines.
9: */
10:
11: /*
12: * virtual terminal additions Copyright 1991, 1992 Todd Fleming
13: * 6/91, 1/92
14: *
15: * Todd Fleming
16: * 1991 Mountainside Drive
17: * Blacksburg, VA 24060
18: */
19:
20: #include <sys/coherent.h>
21: #include <sys/sched.h>
22: #include <errno.h>
23: #include <sys/stat.h>
24: #include <sys/io.h>
25: #include <sys/tty.h>
26: #include <sys/timeout.h>
27: #include <sys/seg.h>
28:
29: /* For beeper */
30: #define TIMCTL 0x43 /* Timer control port */
31: #define TIMCNT 0x42 /* Counter timer port */
32: #define PORTB 0x61 /* Port containing speaker enable */
33: #define FREQ ((int)(1193181L/440)) /* Counter for 440 Hz. tone */
34:
35: int mmtime();
36:
37: char mmbeeps; /* number of ticks remaining on bell */
38: char mmesc; /* last unserviced escape character */
39: char mmescterm; /* terminal for -^ (TBF) */
40: int mmcrtsav = 1; /* crt saver enabled */
41: int mmvcnt = 900; /* seconds remaining before crt saver is activated */
42:
43: /*
44: * For virtual terminals
45: * (TBF)
46: */
47:
48: #define NVIRTERMS 4 /* # of virtual terminals */
49: /* must also be set in mmas.s and kb.c */
50:
51: struct mmspecspacestruct /* C translation of mmas.s data structure */
52: {
53: unsigned *FUNC,PORT,BASE;
54: unsigned char ROW,COL;
55: unsigned POS;
56: unsigned char ATTR,N1,N2,BROW,EROW,LROW,SROW,SCOL,IBROW,IEROW;
57: unsigned INVIS;
58: unsigned char SLOW,WRAP,CURTERM,UNUSED;
59: } extern mmspecspace[NVIRTERMS];
60:
61: unsigned mmcurvirterm=1; /* current virtual terminal */
62: SEG *mmswapsegs[NVIRTERMS]; /* holders for swap buffers */
63: unsigned mmvideobase; /* base address of video screen */
64: unsigned mmtermbufs[NVIRTERMS]; /* selectors for swap buffers */
65: int mmvirtermsinitialized=0;
66: extern mmblankbuf(); /* buffer copy function */
67: extern mmbufcopy(); /* buffer blanking function */
68: extern unsigned mmcursor; /* update cursor */
69: mminitvirterms(); /* initialize virtual terminals */
70: mmchangeterm(); /* change current terminal */
71:
72: extern TTY istty[NVIRTERMS+1];
73:
74: /*
75: * Start the output stream.
76: * Called from `ttwrite' and `isrint' routines.
77: */
78: TIM mmtim;
79:
80: mmstart(tp)
81: register TTY *tp;
82: {
83: int c;
84: IO iob;
85: static int mmbegun;
86:
87: while ((tp->t_flags&T_STOP) == 0) {
88: if ((c = ttout(tp)) < 0)
89: break;
90: iob.io_seg = IOSYS;
91: iob.io_ioc = 1;
92: iob.io_base = &c;
93: iob.io_flag = 0;
94: mmwrite( makedev(2,0), &iob );
95: }
96:
97: if (mmbegun == 0) {
98: ++mmbegun;
99: timeout(&mmtim, HZ/10, mmtime, (char *)tp);
100: }
101: }
102:
103: /*
104: * Initialize virtual terminals (TBF)
105: * called from kb.c
106: */
107:
108: mminitvirterms()
109: {
110: if(!mmvirtermsinitialized)
111: {
112: int i;
113: mmvirtermsinitialized=1;
114: mmvideobase=mmspecspace[0].BASE; /* save video address */
115: mmcurvirterm=1; /* set current terminal */
116: for(i=0;i<NVIRTERMS;i++)
117: {
118: mmswapsegs[i]=salloc((fsize_t)80*25*2,SFSYST|SFHIGH|SFNSWP); /* allocate virtual */
119: mmtermbufs[i]=mmswapsegs[i]->s_faddr>>16; /* terminal space */
120: if(i)
121: {
122: mmspecspace[i]=mmspecspace[0]; /* copy data structures */
123: mmspecspace[i].BASE=mmtermbufs[i]; /* assign buffers to terminals */
124: mmblankbuf(mmtermbufs[i]); /* blank out buf i */
125: mmspecspace[i].CURTERM=0; /* terms 2-NVIRTERMS switched off */
126: }
127: else
128: mmspecspace[0].CURTERM=1; /* term 1 switched on */
129: }
130: }
131: }
132:
133: /*
134: * Change virtual terminals (TBF)
135: * mmcurvirterm = virtual terminal from 1 to NVIRTERMS
136: * mmtermbufs[from 0 to NVIRTERMS-1]
137: * mmspecspace[from 0 to NVIRTERMS-1]
138: */
139:
140: mmchangeterm(term)
141: unsigned term;
142: {
143: if(term!=mmcurvirterm)
144: {
145: unsigned *funchold;
146:
147: mmbufcopy(mmtermbufs[mmcurvirterm-1],mmvideobase); /* dest, source */
148: mmbufcopy(mmvideobase,mmtermbufs[term-1]);
149:
150: mmspecspace[mmcurvirterm-1].BASE=mmtermbufs[mmcurvirterm-1];
151: mmspecspace[mmcurvirterm-1].CURTERM=0;/* disable prev. term */
152: mmspecspace[term-1].BASE=mmvideobase;
153: mmspecspace[term-1].CURTERM=1; /* enable new term */
154: mmcurvirterm=term; /* note the change */
155:
156: funchold=mmspecspace[term-1].FUNC; /* preserve state */
157: mmspecspace[term-1].FUNC=&mmcursor; /* set mmgo to update cursor */
158: mmgo(NULL,makedev(2,term)); /* update cursor */
159: mmspecspace[term-1].FUNC=funchold; /* restore state */
160: }
161: }
162:
163: mmtime(xp)
164: char *xp;
165: {
166: register int s;
167:
168: s = sphi();
169: if (mmbeeps < 0) {
170: mmbeeps = 2;
171: outb(TIMCTL, 0xB6); /* Timer 2, lsb, msb, binary */
172: outb(TIMCNT, FREQ&0xFF);
173: outb(TIMCNT, FREQ>>8);
174: outb(PORTB, inb(PORTB) | 03); /* Turn speaker on */
175: }
176: else if ((mmbeeps > 0) && (--mmbeeps == 0))
177: outb( PORTB, inb(PORTB) & ~03 );
178:
179: if (mmesc) {
180: ismmfunc(mmesc,mmescterm);
181: mmesc = 0;
182: }
183: spl(s);
184:
185: ttstart( (TTY *) xp );
186:
187: timeout(&mmtim, HZ/10, mmtime, xp);
188: }
189:
190: /**
191: *
192: * void
193: * mmwatch() -- turn video display off after 15 minutes inactivity.
194: */
195: void
196: mmwatch()
197: {
198: if ( (mmcrtsav > 0) && (mmvcnt > 0) && (--mmvcnt == 0) )
199: mm_voff();
200: }
201:
202: mmwrite( dev, iop )
203: dev_t dev;
204: register IO *iop;
205: {
206: int ioc;
207: int s;
208:
209: ioc = iop->io_ioc;
210:
211: /*
212: * Kernel writes.
213: */
214: if (iop->io_seg == IOSYS) {
215: mmescterm=mmcurvirterm; /* for kb esc processing */
216: while (mmgo(iop,makedev(2,mmcurvirterm)))
217: ;
218: if(!mmvirtermsinitialized)
219: mminitvirterms(); /* TBF */
220: }
221:
222: /*
223: * Blocking user writes.
224: */
225: else
226: {
227: if(minor(dev)==0)
228: dev=makedev(2,mmcurvirterm); /*TBF */
229:
230: if ( (iop->io_flag & IONDLY) == 0 ) {
231: do {
232: while (istty[minor(dev)].t_flags & T_STOP) {
233: s = sphi();
234: istty[minor(dev)].t_flags |= T_HILIM;
235: sleep((char*) &istty[minor(dev)].t_oq,
236: CVTTOUT, IVTTOUT, SVTTOUT);
237: spl( s );
238: }
239: /*
240: * Signal received.
241: */
242: if ( SELF->p_ssig && nondsig() ) {
243: kbunscroll(); /* update kbd LEDS */
244: /*
245: * No data transferred yet.
246: */
247: if ( ioc == iop->io_ioc )
248: u.u_error = EINTR;
249: /*
250: * Transfer remaining data
251: * without pausing after scrolling.
252: */
253: else
254: {
255: mmescterm=minor(dev);
256: while ( mmgo(iop,dev) )
257: ;
258: }
259: return;
260: }
261: mmescterm=minor(dev);
262: mmgo(iop,dev);
263: } while ( iop->io_ioc );
264: }
265:
266: /*
267: * Non-blocking user writes with output stopped.
268: */
269: else if ( istty[minor(dev)].t_flags & T_STOP ) {
270: u.u_error = EAGAIN;
271: return;
272: }
273:
274: /*
275: * Non-blocking user writes do not pause after scrolling.
276: */
277: else {
278: mmescterm=minor(dev);
279: while ( mmgo(iop,dev) )
280: ;
281: }
282: }
283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.