Subversion Repositories HelenOS-historic

Rev

Rev 1547 | Rev 1562 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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