source: mainline/fb/ega.c@ dc5a0fe1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since dc5a0fe1 was dc5a0fe1, checked in by Jakub Vana <jakub.vana@…>, 19 years ago

Ega cursor movement support

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 * Copyright (C) 2006 Ondrej Palkovsky
3 * All rights reserved.
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 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <align.h>
30#include <async.h>
31#include <ipc/ipc.h>
32#include <errno.h>
33#include <stdio.h>
34#include <ddi.h>
35#include <sysinfo.h>
36#include <as.h>
37#include <ipc/fb.h>
38#include <ipc/ipc.h>
39#include <ipc/ns.h>
40#include <ipc/services.h>
41
42#include "ega.h"
43#include "../console/screenbuffer.h"
44#include "main.h"
45
46
47#define EGA_IO_ADDRESS 0x3d4
48#define EGA_IO_SIZE 2
49
50typedef unsigned char u8;
51typedef unsigned short u16;
52typedef unsigned int u32;
53
54
55/* Allow only 1 connection */
56static int client_connected = 0;
57
58static unsigned int scr_width;
59static unsigned int scr_height;
60static char *scr_addr;
61
62static unsigned int style = 0x0f;
63
64static inline void outb(u16 port, u8 b)
65{
66 asm volatile ("outb %0, %1\n" :: "a" (b), "d" (port));
67}
68
69static inline void outw(u16 port, u16 w)
70{
71 asm volatile ("outw %0, %1\n" :: "a" (w), "d" (port));
72}
73
74static inline void outl(u16 port, u32 l)
75{
76 asm volatile ("outl %0, %1\n" :: "a" (l), "d" (port));
77}
78
79static inline u8 inb(u16 port)
80{
81 u8 val;
82
83 asm volatile ("inb %1, %0 \n" : "=a" (val) : "d"(port));
84 return val;
85}
86
87static inline u16 inw(u16 port)
88{
89 u16 val;
90
91 asm volatile ("inw %1, %0 \n" : "=a" (val) : "d"(port));
92 return val;
93}
94
95static inline u32 inl(u16 port)
96{
97 u32 val;
98
99 asm volatile ("inl %1, %0 \n" : "=a" (val) : "d"(port));
100 return val;
101}
102
103
104
105
106static void clrscr(void)
107{
108 int i;
109
110 for (i=0; i < scr_width*scr_height; i++) {
111 scr_addr[i*2] = ' ';
112 scr_addr[i*2+1] = style;
113 }
114}
115
116void cursor_goto(unsigned int row, unsigned int col)
117{
118 int ega_cursor;
119
120 ega_cursor=col+scr_width*row;
121
122 outb(EGA_IO_ADDRESS , 0xe);
123 outb(EGA_IO_ADDRESS + 1, (ega_cursor >>8) & 0xff);
124 outb(EGA_IO_ADDRESS , 0xf);
125 outb(EGA_IO_ADDRESS + 1, ega_cursor & 0xff);
126}
127
128void cursor_disable(void)
129{
130 u8 stat;
131 outb(EGA_IO_ADDRESS , 0xa);
132 stat=inb(EGA_IO_ADDRESS + 1);
133 outb(EGA_IO_ADDRESS , 0xa);
134 outb(EGA_IO_ADDRESS +1 ,stat | (1<<5) );
135}
136
137void cursor_enable(void)
138{
139 u8 stat;
140 outb(EGA_IO_ADDRESS , 0xa);
141 stat=inb(EGA_IO_ADDRESS + 1);
142 outb(EGA_IO_ADDRESS , 0xa);
143 outb(EGA_IO_ADDRESS +1 ,stat & (~(1<<5)) );
144}
145
146static void printchar(char c, unsigned int row, unsigned int col)
147{
148 scr_addr[(row*scr_width + col)*2] = c;
149 scr_addr[(row*scr_width + col)*2+1] = style;
150
151 cursor_goto(row,col+1);
152}
153
154static void draw_text_data(keyfield_t *data)
155{
156 int i;
157
158 for (i=0; i < scr_width*scr_height; i++) {
159 scr_addr[i*2] = data[i].character;
160 if (data[i].style.fg_color > data[i].style.bg_color)
161 scr_addr[i*2+1] = 0x0f;
162 else
163 scr_addr[i*2+1] = 0xf0;
164 }
165}
166
167static void ega_client_connection(ipc_callid_t iid, ipc_call_t *icall)
168{
169 int retval;
170 ipc_callid_t callid;
171 ipc_call_t call;
172 char c;
173 unsigned int row, col;
174 int bgcolor,fgcolor;
175 keyfield_t *interbuf = NULL;
176 size_t intersize = 0;
177
178 if (client_connected) {
179 ipc_answer_fast(iid, ELIMIT, 0,0);
180 return;
181 }
182 client_connected = 1;
183 ipc_answer_fast(iid, 0, 0, 0); /* Accept connection */
184
185 while (1) {
186 callid = async_get_call(&call);
187 switch (IPC_GET_METHOD(call)) {
188 case IPC_M_PHONE_HUNGUP:
189 client_connected = 0;
190 ipc_answer_fast(callid,0,0,0);
191 return; /* Exit thread */
192 case IPC_M_AS_AREA_SEND:
193 /* We accept one area for data interchange */
194 intersize = IPC_GET_ARG2(call);
195 if (intersize >= scr_width*scr_height*sizeof(*interbuf)) {
196 receive_comm_area(callid,&call,(void **)&interbuf);
197 continue;
198 }
199 retval = EINVAL;
200 break;
201 case FB_DRAW_TEXT_DATA:
202 if (!interbuf) {
203 retval = EINVAL;
204 break;
205 }
206 draw_text_data(interbuf);
207 retval = 0;
208 break;
209 case FB_GET_CSIZE:
210 ipc_answer_fast(callid, 0, scr_height, scr_width);
211 continue;
212 case FB_CLEAR:
213 clrscr();
214 retval = 0;
215 break;
216 case FB_PUTCHAR:
217 c = IPC_GET_ARG1(call);
218 row = IPC_GET_ARG2(call);
219 col = IPC_GET_ARG3(call);
220 if (col >= scr_width || row >= scr_height) {
221 retval = EINVAL;
222 break;
223 }
224 printchar(c,row,col);
225 retval = 0;
226 break;
227 case FB_CURSOR_GOTO:
228 row = IPC_GET_ARG1(call);
229 col = IPC_GET_ARG2(call);
230 if (row >= scr_height || col >= scr_width) {
231 retval = EINVAL;
232 break;
233 }
234 cursor_goto(row,col);
235 retval = 0;
236 break;
237 case FB_CURSOR_VISIBILITY:
238 if(IPC_GET_ARG1(call))
239 cursor_enable();
240 else
241 cursor_disable();
242 retval = 0;
243 break;
244 case FB_SET_STYLE:
245 fgcolor = IPC_GET_ARG1(call);
246 bgcolor = IPC_GET_ARG2(call);
247 if (fgcolor > bgcolor)
248 style = 0x0f;
249 else
250 style = 0xf0;
251 default:
252 retval = ENOENT;
253 }
254 ipc_answer_fast(callid,retval,0,0);
255 }
256}
257
258int ega_init(void)
259{
260 void *ega_ph_addr;
261 size_t sz;
262
263
264 ega_ph_addr=(void *)sysinfo_value("fb.address.physical");
265 scr_width=sysinfo_value("fb.width");
266 scr_height=sysinfo_value("fb.height");
267 iospace_enable(task_get_id(),(void *)EGA_IO_ADDRESS,2);
268
269 sz = scr_width*scr_height*2;
270 scr_addr = as_get_mappable_page(sz);
271
272 map_physmem(ega_ph_addr, scr_addr, ALIGN_UP(sz,PAGE_SIZE)>>PAGE_WIDTH,
273 AS_AREA_READ | AS_AREA_WRITE);
274
275 async_set_client_connection(ega_client_connection);
276
277 clrscr();
278
279 return 0;
280}
281
Note: See TracBrowser for help on using the repository browser.