Subversion Repositories HelenOS

Rev

Rev 4223 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4223 Rev 4320
1
/*
1
/*
2
 * Copyright (c) 2001-2004 Jakub Jermar
2
 * Copyright (c) 2001-2004 Jakub Jermar
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
/** @addtogroup genarch_drivers
29
/** @addtogroup genarch_drivers
30
 * @{
30
 * @{
31
 */
31
 */
32
/**
32
/**
33
 * @file
33
 * @file
34
 * @brief EGA driver.
34
 * @brief EGA driver.
35
 */
35
 */
36
 
36
 
37
#include <genarch/drivers/ega/ega.h>
37
#include <genarch/drivers/ega/ega.h>
38
#include <putchar.h>
38
#include <putchar.h>
39
#include <mm/page.h>
39
#include <mm/page.h>
40
#include <mm/as.h>
40
#include <mm/as.h>
41
#include <mm/slab.h>
41
#include <mm/slab.h>
42
#include <arch/mm/page.h>
42
#include <arch/mm/page.h>
43
#include <synch/spinlock.h>
43
#include <synch/spinlock.h>
44
#include <arch/types.h>
44
#include <arch/types.h>
45
#include <arch/asm.h>
45
#include <arch/asm.h>
46
#include <memstr.h>
46
#include <memstr.h>
47
#include <string.h>
47
#include <string.h>
48
#include <console/chardev.h>
48
#include <console/chardev.h>
49
#include <console/console.h>
49
#include <console/console.h>
50
#include <sysinfo/sysinfo.h>
50
#include <sysinfo/sysinfo.h>
51
#include <ddi/ddi.h>
51
#include <ddi/ddi.h>
52
 
52
 
53
/*
53
/*
54
 * The EGA driver.
54
 * The EGA driver.
55
 * Simple and short. Function for displaying characters and "scrolling".
55
 * Simple and short. Function for displaying characters and "scrolling".
56
 */
56
 */
57
 
57
 
58
SPINLOCK_INITIALIZE(egalock);
58
SPINLOCK_INITIALIZE(egalock);
59
static uint32_t ega_cursor;
59
static uint32_t ega_cursor;
60
static uint8_t *videoram;
60
static uint8_t *videoram;
61
static uint8_t *backbuf;
61
static uint8_t *backbuf;
62
static ioport8_t *ega_base;
62
static ioport8_t *ega_base;
63
 
63
 
64
#define SPACE  0x20
64
#define SPACE  0x20
65
#define STYLE  0x1e
65
#define STYLE  0x1e
66
#define INVAL  0x17
66
#define INVAL  0x17
67
 
67
 
68
#define EMPTY_CHAR  ((STYLE << 8) | SPACE)
68
#define EMPTY_CHAR  ((STYLE << 8) | SPACE)
69
 
69
 
70
static uint16_t ega_oem_glyph(const wchar_t ch)
70
static uint16_t ega_oem_glyph(const wchar_t ch)
71
{
71
{
72
    if ((ch >= 0x0000) && (ch <= 0x007f))
72
    if ((ch >= 0x0000) && (ch <= 0x007f))
73
        return ch;
73
        return ch;
74
   
74
   
75
    if (ch == 0x00a0)
75
    if (ch == 0x00a0)
76
        return 255;
76
        return 255;
77
   
77
   
78
    if (ch == 0x00a1)
78
    if (ch == 0x00a1)
79
        return 173;
79
        return 173;
80
   
80
   
81
    if ((ch >= 0x00a2) && (ch <= 0x00a3))
81
    if ((ch >= 0x00a2) && (ch <= 0x00a3))
82
        return (ch - 7);
82
        return (ch - 7);
83
   
83
   
84
    if (ch == 0x00a5)
84
    if (ch == 0x00a5)
85
        return 157;
85
        return 157;
86
   
86
   
87
    if (ch == 0x00aa)
87
    if (ch == 0x00aa)
88
        return 166;
88
        return 166;
89
   
89
   
90
    if (ch == 0x00ab)
90
    if (ch == 0x00ab)
91
        return 174;
91
        return 174;
92
   
92
   
93
    if (ch == 0x00ac)
93
    if (ch == 0x00ac)
94
        return 170;
94
        return 170;
95
   
95
   
96
    if (ch == 0x00b0)
96
    if (ch == 0x00b0)
97
        return 248;
97
        return 248;
98
   
98
   
99
    if (ch == 0x00b1)
99
    if (ch == 0x00b1)
100
        return 241;
100
        return 241;
101
   
101
   
102
    if (ch == 0x00b2)
102
    if (ch == 0x00b2)
103
        return 253;
103
        return 253;
104
   
104
   
105
    if (ch == 0x00b5)
105
    if (ch == 0x00b5)
106
        return 230;
106
        return 230;
107
   
107
   
108
    if (ch == 0x00b7)
108
    if (ch == 0x00b7)
109
        return 250;
109
        return 250;
110
   
110
   
111
    if (ch == 0x00ba)
111
    if (ch == 0x00ba)
112
        return 167;
112
        return 167;
113
   
113
   
114
    if (ch == 0x00bb)
114
    if (ch == 0x00bb)
115
        return 175;
115
        return 175;
116
   
116
   
117
    if (ch == 0x00bc)
117
    if (ch == 0x00bc)
118
        return 172;
118
        return 172;
119
   
119
   
120
    if (ch == 0x00bd)
120
    if (ch == 0x00bd)
121
        return 171;
121
        return 171;
122
   
122
   
123
    if (ch == 0x00bf)
123
    if (ch == 0x00bf)
124
        return 168;
124
        return 168;
125
   
125
   
126
    if ((ch >= 0x00c4) && (ch <= 0x00c5))
126
    if ((ch >= 0x00c4) && (ch <= 0x00c5))
127
        return (ch - 54);
127
        return (ch - 54);
128
   
128
   
129
    if (ch == 0x00c6)
129
    if (ch == 0x00c6)
130
        return 146;
130
        return 146;
131
   
131
   
132
    if (ch == 0x00c7)
132
    if (ch == 0x00c7)
133
        return 128;
133
        return 128;
134
   
134
   
135
    if (ch == 0x00c9)
135
    if (ch == 0x00c9)
136
        return 144;
136
        return 144;
137
   
137
   
138
    if (ch == 0x00d1)
138
    if (ch == 0x00d1)
139
        return 165;
139
        return 165;
140
   
140
   
141
    if (ch == 0x00d6)
141
    if (ch == 0x00d6)
142
        return 153;
142
        return 153;
143
   
143
   
144
    if (ch == 0x00dc)
144
    if (ch == 0x00dc)
145
        return 154;
145
        return 154;
146
   
146
   
147
    if (ch == 0x00df)
147
    if (ch == 0x00df)
148
        return 225;
148
        return 225;
149
   
149
   
150
    if (ch == 0x00e0)
150
    if (ch == 0x00e0)
151
        return 133;
151
        return 133;
152
   
152
   
153
    if (ch == 0x00e1)
153
    if (ch == 0x00e1)
154
        return 160;
154
        return 160;
155
   
155
   
156
    if (ch == 0x00e2)
156
    if (ch == 0x00e2)
157
        return 131;
157
        return 131;
158
   
158
   
159
    if (ch == 0x00e4)
159
    if (ch == 0x00e4)
160
        return 132;
160
        return 132;
161
   
161
   
162
    if (ch == 0x00e5)
162
    if (ch == 0x00e5)
163
        return 134;
163
        return 134;
164
   
164
   
165
    if (ch == 0x00e6)
165
    if (ch == 0x00e6)
166
        return 145;
166
        return 145;
167
   
167
   
168
    if (ch == 0x00e7)
168
    if (ch == 0x00e7)
169
        return 135;
169
        return 135;
170
   
170
   
171
    if (ch == 0x00e8)
171
    if (ch == 0x00e8)
172
        return 138;
172
        return 138;
173
   
173
   
174
    if (ch == 0x00e9)
174
    if (ch == 0x00e9)
175
        return 130;
175
        return 130;
176
   
176
   
177
    if ((ch >= 0x00ea) && (ch <= 0x00eb))
177
    if ((ch >= 0x00ea) && (ch <= 0x00eb))
178
        return (ch - 98);
178
        return (ch - 98);
179
   
179
   
180
    if (ch == 0x00ec)
180
    if (ch == 0x00ec)
181
        return 141;
181
        return 141;
182
   
182
   
183
    if (ch == 0x00ed)
183
    if (ch == 0x00ed)
184
        return 161;
184
        return 161;
185
   
185
   
186
    if (ch == 0x00ee)
186
    if (ch == 0x00ee)
187
        return 140;
187
        return 140;
188
   
188
   
189
    if (ch == 0x00ef)
189
    if (ch == 0x00ef)
190
        return 139;
190
        return 139;
191
   
191
   
192
    if (ch == 0x00f1)
192
    if (ch == 0x00f1)
193
        return 164;
193
        return 164;
194
   
194
   
195
    if (ch == 0x00f2)
195
    if (ch == 0x00f2)
196
        return 149;
196
        return 149;
197
   
197
   
198
    if (ch == 0x00f3)
198
    if (ch == 0x00f3)
199
        return 162;
199
        return 162;
200
   
200
   
201
    if (ch == 0x00f4)
201
    if (ch == 0x00f4)
202
        return 147;
202
        return 147;
203
   
203
   
204
    if (ch == 0x00f6)
204
    if (ch == 0x00f6)
205
        return 148;
205
        return 148;
206
   
206
   
207
    if (ch == 0x00f7)
207
    if (ch == 0x00f7)
208
        return 246;
208
        return 246;
209
   
209
   
210
    if (ch == 0x00f9)
210
    if (ch == 0x00f9)
211
        return 151;
211
        return 151;
212
   
212
   
213
    if (ch == 0x00fa)
213
    if (ch == 0x00fa)
214
        return 163;
214
        return 163;
215
   
215
   
216
    if (ch == 0x00fb)
216
    if (ch == 0x00fb)
217
        return 150;
217
        return 150;
218
   
218
   
219
    if (ch == 0x00fc)
219
    if (ch == 0x00fc)
220
        return 129;
220
        return 129;
221
   
221
   
222
    if (ch == 0x00ff)
222
    if (ch == 0x00ff)
223
        return 152;
223
        return 152;
224
   
224
   
225
    if (ch == 0x0192)
225
    if (ch == 0x0192)
226
        return 159;
226
        return 159;
227
   
227
   
228
    if (ch == 0x0393)
228
    if (ch == 0x0393)
229
        return 226;
229
        return 226;
230
   
230
   
231
    if (ch == 0x0398)
231
    if (ch == 0x0398)
232
        return 233;
232
        return 233;
233
   
233
   
234
    if (ch == 0x03a3)
234
    if (ch == 0x03a3)
235
        return 228;
235
        return 228;
236
   
236
   
237
    if (ch == 0x03a6)
237
    if (ch == 0x03a6)
238
        return 232;
238
        return 232;
239
   
239
   
240
    if (ch == 0x03a9)
240
    if (ch == 0x03a9)
241
        return 234;
241
        return 234;
242
   
242
   
243
    if (ch == 0x03b1)
243
    if (ch == 0x03b1)
244
        return 224;
244
        return 224;
245
   
245
   
246
    if (ch == 0x03b4)
246
    if (ch == 0x03b4)
247
        return 235;
247
        return 235;
248
   
248
   
249
    if (ch == 0x03b5)
249
    if (ch == 0x03b5)
250
        return 238;
250
        return 238;
251
   
251
   
252
    if (ch == 0x03c0)
252
    if (ch == 0x03c0)
253
        return 227;
253
        return 227;
254
   
254
   
255
    if (ch == 0x03c3)
255
    if (ch == 0x03c3)
256
        return 229;
256
        return 229;
257
   
257
   
258
    if (ch == 0x03c4)
258
    if (ch == 0x03c4)
259
        return 231;
259
        return 231;
260
   
260
   
261
    if (ch == 0x03c6)
261
    if (ch == 0x03c6)
262
        return 237;
262
        return 237;
263
   
263
   
264
    if (ch == 0x207f)
264
    if (ch == 0x207f)
265
        return 252;
265
        return 252;
266
   
266
   
267
    if (ch == 0x20a7)
267
    if (ch == 0x20a7)
268
        return 158;
268
        return 158;
269
   
269
   
270
    if (ch == 0x2219)
270
    if (ch == 0x2219)
271
        return 249;
271
        return 249;
272
   
272
   
273
    if (ch == 0x221a)
273
    if (ch == 0x221a)
274
        return 251;
274
        return 251;
275
   
275
   
276
    if (ch == 0x221e)
276
    if (ch == 0x221e)
277
        return 236;
277
        return 236;
278
   
278
   
279
    if (ch == 0x2229)
279
    if (ch == 0x2229)
280
        return 239;
280
        return 239;
281
   
281
   
282
    if (ch == 0x2248)
282
    if (ch == 0x2248)
283
        return 247;
283
        return 247;
284
   
284
   
285
    if (ch == 0x2261)
285
    if (ch == 0x2261)
286
        return 240;
286
        return 240;
287
   
287
   
288
    if (ch == 0x2264)
288
    if (ch == 0x2264)
289
        return 243;
289
        return 243;
290
   
290
   
291
    if (ch == 0x2265)
291
    if (ch == 0x2265)
292
        return 242;
292
        return 242;
293
   
293
   
294
    if (ch == 0x2310)
294
    if (ch == 0x2310)
295
        return 169;
295
        return 169;
296
   
296
   
297
    if ((ch >= 0x2320) && (ch <= 0x2321))
297
    if ((ch >= 0x2320) && (ch <= 0x2321))
298
        return (ch - 8748);
298
        return (ch - 8748);
299
   
299
   
300
    if (ch == 0x2500)
300
    if (ch == 0x2500)
301
        return 196;
301
        return 196;
302
   
302
   
303
    if (ch == 0x2502)
303
    if (ch == 0x2502)
304
        return 179;
304
        return 179;
305
   
305
   
306
    if (ch == 0x250c)
306
    if (ch == 0x250c)
307
        return 218;
307
        return 218;
308
   
308
   
309
    if (ch == 0x2510)
309
    if (ch == 0x2510)
310
        return 191;
310
        return 191;
311
   
311
   
312
    if (ch == 0x2514)
312
    if (ch == 0x2514)
313
        return 192;
313
        return 192;
314
   
314
   
315
    if (ch == 0x2518)
315
    if (ch == 0x2518)
316
        return 217;
316
        return 217;
317
   
317
   
318
    if (ch == 0x251c)
318
    if (ch == 0x251c)
319
        return 195;
319
        return 195;
320
   
320
   
321
    if (ch == 0x2524)
321
    if (ch == 0x2524)
322
        return 180;
322
        return 180;
323
   
323
   
324
    if (ch == 0x252c)
324
    if (ch == 0x252c)
325
        return 194;
325
        return 194;
326
   
326
   
327
    if (ch == 0x2534)
327
    if (ch == 0x2534)
328
        return 193;
328
        return 193;
329
   
329
   
330
    if (ch == 0x253c)
330
    if (ch == 0x253c)
331
        return 197;
331
        return 197;
332
   
332
   
333
    if (ch == 0x2550)
333
    if (ch == 0x2550)
334
        return 205;
334
        return 205;
335
   
335
   
336
    if (ch == 0x2551)
336
    if (ch == 0x2551)
337
        return 186;
337
        return 186;
338
   
338
   
339
    if ((ch >= 0x2552) && (ch <= 0x2553))
339
    if ((ch >= 0x2552) && (ch <= 0x2553))
340
        return (ch - 9341);
340
        return (ch - 9341);
341
   
341
   
342
    if (ch == 0x2554)
342
    if (ch == 0x2554)
343
        return 201;
343
        return 201;
344
   
344
   
345
    if (ch == 0x2555)
345
    if (ch == 0x2555)
346
        return 184;
346
        return 184;
347
   
347
   
348
    if (ch == 0x2556)
348
    if (ch == 0x2556)
349
        return 183;
349
        return 183;
350
   
350
   
351
    if (ch == 0x2557)
351
    if (ch == 0x2557)
352
        return 187;
352
        return 187;
353
   
353
   
354
    if (ch == 0x2558)
354
    if (ch == 0x2558)
355
        return 212;
355
        return 212;
356
   
356
   
357
    if (ch == 0x2559)
357
    if (ch == 0x2559)
358
        return 211;
358
        return 211;
359
   
359
   
360
    if (ch == 0x255a)
360
    if (ch == 0x255a)
361
        return 200;
361
        return 200;
362
   
362
   
363
    if (ch == 0x255b)
363
    if (ch == 0x255b)
364
        return 190;
364
        return 190;
365
   
365
   
366
    if (ch == 0x255c)
366
    if (ch == 0x255c)
367
        return 189;
367
        return 189;
368
   
368
   
369
    if (ch == 0x255d)
369
    if (ch == 0x255d)
370
        return 188;
370
        return 188;
371
   
371
   
372
    if ((ch >= 0x255e) && (ch <= 0x255f))
372
    if ((ch >= 0x255e) && (ch <= 0x255f))
373
        return (ch - 9368);
373
        return (ch - 9368);
374
   
374
   
375
    if (ch == 0x2560)
375
    if (ch == 0x2560)
376
        return 204;
376
        return 204;
377
   
377
   
378
    if ((ch >= 0x2561) && (ch <= 0x2562))
378
    if ((ch >= 0x2561) && (ch <= 0x2562))
379
        return (ch - 9388);
379
        return (ch - 9388);
380
   
380
   
381
    if (ch == 0x2563)
381
    if (ch == 0x2563)
382
        return 185;
382
        return 185;
383
   
383
   
384
    if ((ch >= 0x2564) && (ch <= 0x2565))
384
    if ((ch >= 0x2564) && (ch <= 0x2565))
385
        return (ch - 9363);
385
        return (ch - 9363);
386
   
386
   
387
    if (ch == 0x2566)
387
    if (ch == 0x2566)
388
        return 203;
388
        return 203;
389
   
389
   
390
    if ((ch >= 0x2567) && (ch <= 0x2568))
390
    if ((ch >= 0x2567) && (ch <= 0x2568))
391
        return (ch - 9368);
391
        return (ch - 9368);
392
   
392
   
393
    if (ch == 0x2569)
393
    if (ch == 0x2569)
394
        return 202;
394
        return 202;
395
   
395
   
396
    if (ch == 0x256a)
396
    if (ch == 0x256a)
397
        return 216;
397
        return 216;
398
   
398
   
399
    if (ch == 0x256b)
399
    if (ch == 0x256b)
400
        return 215;
400
        return 215;
401
   
401
   
402
    if (ch == 0x256c)
402
    if (ch == 0x256c)
403
        return 206;
403
        return 206;
404
   
404
   
405
    if (ch == 0x2580)
405
    if (ch == 0x2580)
406
        return 223;
406
        return 223;
407
   
407
   
408
    if (ch == 0x2584)
408
    if (ch == 0x2584)
409
        return 220;
409
        return 220;
410
   
410
   
411
    if (ch == 0x2588)
411
    if (ch == 0x2588)
412
        return 219;
412
        return 219;
413
   
413
   
414
    if (ch == 0x258c)
414
    if (ch == 0x258c)
415
        return 221;
415
        return 221;
416
   
416
   
417
    if (ch == 0x2590)
417
    if (ch == 0x2590)
418
        return 222;
418
        return 222;
419
   
419
   
420
    if ((ch >= 0x2591) && (ch <= 0x2593))
420
    if ((ch >= 0x2591) && (ch <= 0x2593))
421
        return (ch - 9441);
421
        return (ch - 9441);
422
   
422
   
423
    return 256;
423
    return 256;
424
}
424
}
425
 
425
 
426
/*
426
/*
427
 * This function takes care of scrolling.
427
 * This function takes care of scrolling.
428
 */
428
 */
429
static void ega_check_cursor(void)
429
static void ega_check_cursor(bool silent)
430
{
430
{
431
    if (ega_cursor < EGA_SCREEN)
431
    if (ega_cursor < EGA_SCREEN)
432
        return;
432
        return;
433
   
433
   
434
    memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2),
-
 
435
        (EGA_SCREEN - EGA_COLS) * 2);
-
 
436
    memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2),
434
    memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2),
437
        (EGA_SCREEN - EGA_COLS) * 2);
435
        (EGA_SCREEN - EGA_COLS) * 2);
438
    memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR);
-
 
439
    memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR);
436
    memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR);
-
 
437
   
-
 
438
    if (!silent) {
-
 
439
        memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2),
-
 
440
            (EGA_SCREEN - EGA_COLS) * 2);
-
 
441
        memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR);
-
 
442
    }
-
 
443
   
440
    ega_cursor = ega_cursor - EGA_COLS;
444
    ega_cursor = ega_cursor - EGA_COLS;
441
}
445
}
442
 
446
 
443
static void ega_show_cursor(void)
447
static void ega_show_cursor(bool silent)
444
{
448
{
-
 
449
    if (!silent) {
445
    pio_write_8(ega_base + EGA_INDEX_REG, 0x0a);
450
        pio_write_8(ega_base + EGA_INDEX_REG, 0x0a);
446
    uint8_t stat = pio_read_8(ega_base + EGA_DATA_REG);
451
        uint8_t stat = pio_read_8(ega_base + EGA_DATA_REG);
447
    pio_write_8(ega_base + EGA_INDEX_REG, 0x0a);
452
        pio_write_8(ega_base + EGA_INDEX_REG, 0x0a);
448
    pio_write_8(ega_base + EGA_DATA_REG, stat & (~(1 << 5)));
453
        pio_write_8(ega_base + EGA_DATA_REG, stat & (~(1 << 5)));
-
 
454
    }
449
}
455
}
450
 
456
 
451
static void ega_move_cursor(void)
457
static void ega_move_cursor(bool silent)
452
{
458
{
-
 
459
    if (!silent) {
453
    pio_write_8(ega_base + EGA_INDEX_REG, 0x0e);
460
        pio_write_8(ega_base + EGA_INDEX_REG, 0x0e);
454
    pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff));
461
        pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff));
455
    pio_write_8(ega_base + EGA_INDEX_REG, 0x0f);
462
        pio_write_8(ega_base + EGA_INDEX_REG, 0x0f);
456
    pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff));
463
        pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff));
-
 
464
    }
457
}
465
}
458
 
466
 
459
static void ega_sync_cursor(void)
467
static void ega_sync_cursor(bool silent)
460
{
468
{
-
 
469
    if (!silent) {
461
    pio_write_8(ega_base + EGA_INDEX_REG, 0x0e);
470
        pio_write_8(ega_base + EGA_INDEX_REG, 0x0e);
462
    uint8_t hi = pio_read_8(ega_base + EGA_DATA_REG);
471
        uint8_t hi = pio_read_8(ega_base + EGA_DATA_REG);
463
    pio_write_8(ega_base + EGA_INDEX_REG, 0x0f);
472
        pio_write_8(ega_base + EGA_INDEX_REG, 0x0f);
464
    uint8_t lo = pio_read_8(ega_base + EGA_DATA_REG);
473
        uint8_t lo = pio_read_8(ega_base + EGA_DATA_REG);
465
   
474
       
466
    ega_cursor = (hi << 8) | lo;
475
        ega_cursor = (hi << 8) | lo;
-
 
476
    } else
-
 
477
        ega_cursor = 0;
467
   
478
   
468
    if (ega_cursor >= EGA_SCREEN)
479
    if (ega_cursor >= EGA_SCREEN)
469
        ega_cursor = 0;
480
        ega_cursor = 0;
470
   
481
   
471
    if ((ega_cursor % EGA_COLS) != 0)
482
    if ((ega_cursor % EGA_COLS) != 0)
472
        ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS;
483
        ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS;
473
   
484
   
474
    memsetw(videoram + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR);
-
 
475
    memsetw(backbuf + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR);
485
    memsetw(backbuf + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR);
476
   
486
   
-
 
487
    if (!silent)
-
 
488
        memsetw(videoram + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR);
-
 
489
   
477
    ega_check_cursor();
490
    ega_check_cursor(silent);
478
    ega_move_cursor();
491
    ega_move_cursor(silent);
479
    ega_show_cursor();
492
    ega_show_cursor(silent);
480
}
493
}
481
 
494
 
482
static void ega_display_char(wchar_t ch, bool silent)
495
static void ega_display_char(wchar_t ch, bool silent)
483
{
496
{
484
    uint16_t index = ega_oem_glyph(ch);
497
    uint16_t index = ega_oem_glyph(ch);
485
    uint8_t glyph;
498
    uint8_t glyph;
486
    uint8_t style;
499
    uint8_t style;
487
   
500
   
488
    if ((index >> 8)) {
501
    if ((index >> 8)) {
489
        glyph = U_SPECIAL;
502
        glyph = U_SPECIAL;
490
        style = INVAL;
503
        style = INVAL;
491
    } else {
504
    } else {
492
        glyph = index & 0xff;
505
        glyph = index & 0xff;
493
        style = STYLE;
506
        style = STYLE;
494
    }
507
    }
495
   
508
   
496
    backbuf[ega_cursor * 2] = glyph;
509
    backbuf[ega_cursor * 2] = glyph;
497
    backbuf[ega_cursor * 2 + 1] = style;
510
    backbuf[ega_cursor * 2 + 1] = style;
498
   
511
   
499
    if (!silent) {
512
    if (!silent) {
500
        videoram[ega_cursor * 2] = glyph;
513
        videoram[ega_cursor * 2] = glyph;
501
        videoram[ega_cursor * 2 + 1] = style;
514
        videoram[ega_cursor * 2 + 1] = style;
502
    }
515
    }
503
}
516
}
504
 
517
 
505
static void ega_putchar(outdev_t *dev __attribute__((unused)), wchar_t ch, bool silent)
518
static void ega_putchar(outdev_t *dev __attribute__((unused)), wchar_t ch, bool silent)
506
{
519
{
507
    ipl_t ipl;
520
    ipl_t ipl;
508
   
521
   
509
    ipl = interrupts_disable();
522
    ipl = interrupts_disable();
510
    spinlock_lock(&egalock);
523
    spinlock_lock(&egalock);
511
   
524
   
512
    switch (ch) {
525
    switch (ch) {
513
    case '\n':
526
    case '\n':
514
        ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS;
527
        ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS;
515
        break;
528
        break;
516
    case '\t':
529
    case '\t':
517
        ega_cursor = (ega_cursor + 8) - ega_cursor % 8;
530
        ega_cursor = (ega_cursor + 8) - ega_cursor % 8;
518
        break;
531
        break;
519
    case '\b':
532
    case '\b':
520
        if (ega_cursor % EGA_COLS)
533
        if (ega_cursor % EGA_COLS)
521
            ega_cursor--;
534
            ega_cursor--;
522
        break;
535
        break;
523
    default:
536
    default:
524
        ega_display_char(ch, silent);
537
        ega_display_char(ch, silent);
525
        ega_cursor++;
538
        ega_cursor++;
526
        break;
539
        break;
527
    }
540
    }
528
    ega_check_cursor();
541
    ega_check_cursor(silent);
529
   
-
 
530
    if (!silent)
-
 
531
        ega_move_cursor();
542
    ega_move_cursor(silent);
532
   
543
   
533
    spinlock_unlock(&egalock);
544
    spinlock_unlock(&egalock);
534
    interrupts_restore(ipl);
545
    interrupts_restore(ipl);
535
}
546
}
536
 
547
 
537
static outdev_t ega_console;
548
static outdev_t ega_console;
538
static outdev_operations_t ega_ops = {
549
static outdev_operations_t ega_ops = {
539
    .write = ega_putchar
550
    .write = ega_putchar
540
};
551
};
541
 
552
 
542
void ega_init(ioport8_t *base, uintptr_t videoram_phys)
553
void ega_init(ioport8_t *base, uintptr_t videoram_phys)
543
{
554
{
544
    /* Initialize the software structure. */
555
    /* Initialize the software structure. */
545
    ega_base = base;
556
    ega_base = base;
546
   
557
   
547
    backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE, 0);
558
    backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE, 0);
548
    if (!backbuf)
559
    if (!backbuf)
549
        panic("Unable to allocate backbuffer.");
560
        panic("Unable to allocate backbuffer.");
550
   
561
   
551
    videoram = (uint8_t *) hw_map(videoram_phys, EGA_VRAM_SIZE);
562
    videoram = (uint8_t *) hw_map(videoram_phys, EGA_VRAM_SIZE);
552
   
563
   
553
    /* Synchronize the back buffer and cursor position. */
564
    /* Synchronize the back buffer and cursor position. */
554
    memcpy(backbuf, videoram, EGA_VRAM_SIZE);
565
    memcpy(backbuf, videoram, EGA_VRAM_SIZE);
555
    ega_sync_cursor();
566
    ega_sync_cursor(silent);
556
   
567
   
557
    outdev_initialize("ega", &ega_console, &ega_ops);
568
    outdev_initialize("ega", &ega_console, &ega_ops);
558
    stdout = &ega_console;
569
    stdout = &ega_console;
559
   
570
   
560
    sysinfo_set_item_val("fb", NULL, true);
571
    sysinfo_set_item_val("fb", NULL, true);
561
    sysinfo_set_item_val("fb.kind", NULL, 2);
572
    sysinfo_set_item_val("fb.kind", NULL, 2);
562
    sysinfo_set_item_val("fb.width", NULL, EGA_COLS);
573
    sysinfo_set_item_val("fb.width", NULL, EGA_COLS);
563
    sysinfo_set_item_val("fb.height", NULL, EGA_ROWS);
574
    sysinfo_set_item_val("fb.height", NULL, EGA_ROWS);
564
    sysinfo_set_item_val("fb.blinking", NULL, true);
575
    sysinfo_set_item_val("fb.blinking", NULL, true);
565
    sysinfo_set_item_val("fb.address.physical", NULL, videoram_phys);
576
    sysinfo_set_item_val("fb.address.physical", NULL, videoram_phys);
566
}
577
}
567
 
578
 
568
void ega_redraw(void)
579
void ega_redraw(void)
569
{
580
{
570
    memcpy(videoram, backbuf, EGA_VRAM_SIZE);
581
    memcpy(videoram, backbuf, EGA_VRAM_SIZE);
571
    ega_move_cursor();
582
    ega_move_cursor(silent);
572
    ega_show_cursor();
583
    ega_show_cursor(silent);
573
}
584
}
574
 
585
 
575
/** @}
586
/** @}
576
 */
587
 */
577
 
588