Subversion Repositories HelenOS

Rev

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

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