/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- splitxy
- mergexy
- lscreen_irq
- lscreen_newline
- lscreen_char
- lscreen_write
- config_lscreen
1 /*
2 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3 * The President and Fellows of Harvard College.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 /*
31 * Driver for full-screen console.
32 *
33 * As of this writing the full-screen console is not supported in
34 * System/161, so this driver is untested and probably broken.
35 */
36 #include <types.h>
37 #include <lib.h>
38 #include <spinlock.h>
39 #include <platform/bus.h>
40 #include <lamebus/lscreen.h>
41 #include "autoconf.h"
42
43 /* Registers (offsets within slot) */
44 #define LSCR_REG_POSN 0 /* Cursor position */
45 #define LSCR_REG_SIZE 4 /* Display size */
46 #define LSCR_REG_CHAR 8 /* Character in */
47 #define LSCR_REG_RIRQ 12 /* Read interrupt status */
48
49 /* Bits in the IRQ registers */
50 #define LSCR_IRQ_ENABLE 1
51 #define LSCR_IRQ_ACTIVE 2
52
53 /* Offset within slot of screen buffer */
54 #define LSCR_SCREEN 32768
55
56 /* Convert a 32-bit X/Y pair to X and Y coordinates. */
57 static
58 inline
59 void
60 splitxy(uint32_t xy, unsigned *x, unsigned *y)
61 {
62 *x = xy >> 16;
63 *y = xy & 0xffff;
64 }
65
66 /* Convert X and Y coordinates to a single 32-bit value. */
67 static
68 inline
69 uint32_t
70 mergexy(unsigned x, unsigned y)
71 {
72 uint32_t val = x;
73
74 return (val << 16) | y;
75 }
76
77 ////////////////////////////////////////////////////////////
78
79 /*
80 * Interrupt handler.
81 */
82 void
83 lscreen_irq(void *vsc)
84 {
85 struct lscreen_softc *sc = vsc;
86 uint32_t ch, x;
87
88 spinlock_acquire(&sc->ls_lock);
89
90 x = bus_read_register(sc->ls_busdata, sc->ls_buspos, LSCR_REG_RIRQ);
91 if (x & LSCR_IRQ_ACTIVE) {
92 ch = bus_read_register(sc->ls_busdata, sc->ls_buspos,
93 LSCR_REG_CHAR);
94 bus_write_register(sc->ls_busdata, sc->ls_buspos,
95 LSCR_REG_RIRQ, LSCR_IRQ_ENABLE);
96
97 spinlock_release(&sc->ls_lock);
98 if (sc->ls_input) {
99 sc->ls_input(sc->ls_devdata, ch);
100 }
101 }
102 else {
103 spinlock_release(&sc->ls_lock);
104 }
105 }
106
107 ////////////////////////////////////////////////////////////
108
109 /*
110 * Handle a newline on the screen.
111 */
112 static
113 void
114 lscreen_newline(struct lscreen_softc *sc)
115 {
116 if (sc->ls_cy >= sc->ls_height-1) {
117 /*
118 * Scroll
119 */
120
121 memmove(sc->ls_screen, sc->ls_screen + sc->ls_width,
122 sc->ls_width * (sc->ls_height-1));
123 bzero(sc->ls_screen + sc->ls_width * (sc->ls_height-1),
124 sc->ls_width);
125 }
126 else {
127 sc->ls_cy++;
128 }
129 sc->ls_cx=0;
130 }
131
132 /*
133 * Handle a printable character being written to the screen.
134 */
135 static
136 void
137 lscreen_char(struct lscreen_softc *sc, int ch)
138 {
139 if (sc->ls_cx >= sc->ls_width) {
140 lscreen_newline(sc);
141 }
142
143 sc->ls_screen[sc->ls_cy*sc->ls_width + sc->ls_cx] = ch;
144 sc->ls_cx++;
145 }
146
147 /*
148 * Send a character to the screen.
149 * This should probably know about backspace and tab.
150 */
151 void
152 lscreen_write(void *vsc, int ch)
153 {
154 struct lscreen_softc *sc = vsc;
155 int ccx, ccy;
156
157 spinlock_acquire(&sc->ls_lock);
158
159 switch (ch) {
160 case '\n': lscreen_newline(sc); break;
161 default: lscreen_char(sc, ch); break;
162 }
163
164 /*
165 * ccx/ccy = corrected cursor position
166 * (The cursor marks the next space text will appear in. But
167 * at the very end of the line, it should not move off the edge.)
168 */
169 ccx = sc->ls_cx;
170 ccy = sc->ls_cy;
171 if (ccx==sc->ls_width) {
172 ccx--;
173 }
174
175 /* Set the cursor position */
176 bus_write_register(sc->ls_busdata, sc->ls_buspos,
177 LSCR_REG_POSN, mergexy(ccx, ccy));
178
179 spinlock_release(&sc->ls_lock);
180 }
181
182 ////////////////////////////////////////////////////////////
183
184 /*
185 * Setup routine called by autoconf.c when an lscreen is found.
186 */
187 int
188 config_lscreen(struct lscreen_softc *sc, int lscreenno)
189 {
190 uint32_t val;
191
192 (void)lscreenno;
193
194 spinlock_init(&sc->ls_lock);
195
196 /*
197 * Enable interrupting.
198 */
199
200 bus_write_register(sc->ls_busdata, sc->ls_buspos,
201 LSCR_REG_RIRQ, LSCR_IRQ_ENABLE);
202
203 /*
204 * Get screen size.
205 */
206 val = bus_read_register(sc->ls_busdata, sc->ls_buspos,
207 LSCR_REG_SIZE);
208 splitxy(val, &sc->ls_width, &sc->ls_height);
209
210 /*
211 * Get cursor position.
212 */
213 val = bus_read_register(sc->ls_busdata, sc->ls_buspos,
214 LSCR_REG_POSN);
215 splitxy(val, &sc->ls_cx, &sc->ls_cy);
216
217 /*
218 * Get a pointer to the memory-mapped screen area.
219 */
220 sc->ls_screen = bus_map_area(sc->ls_busdata, sc->ls_buspos,
221 LSCR_SCREEN);
222
223 return 0;
224 }
225