OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [armnommu/] [drivers/] [char/] [console.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1622 jcastillo
/*
2
 * linux/arch/arm/drivers/char/console.c
3
 *
4
 * Modifications (C) 1995, 1996 Russell King
5
 */
6
 
7
/*
8
 * This module exports the console io functions:
9
 *
10
 *  'int           vcd_init (struct vt *vt, int kmallocok, unsigned long *kmem)'
11
 *  'unsigned long vcd_pre_init (unsigned long kmem, struct vt *vt)'
12
 *  'void          vcd_disallocate (struct vt *vt)'
13
 *  'int           vcd_resize (unsigned long lines, unsigned long cols)'
14
 *  'void          vcd_blankscreen (int nopowersave)'
15
 *  'void          vcd_unblankscreen (void)'
16
 *  'void          vcd_savestate (const struct vt *vt, int blanked)'
17
 *  'void          vcd_restorestate (const struct vt *vt)'
18
 *  'void          vcd_setup_graphics (const struct vt *vt)'
19
 *  'int           vcd_write (const struct vt *vt, int from_user, const unsigned char *buf, int count)'
20
 *  'int           vcd_ioctl (const struct vt *vt, int cmd, unsigned long arg)'
21
 *
22
 *
23
 *      'unsigned long con_init(unsigned long)'
24
 * S    'int con_open(struct tty_struct *tty,struct file *filp)'
25
 * S    'void con_write(struct tty_struct *tty)'
26
 * S    'void console_print(const char *b)'
27
 *
28
 *      'void unblank_screen(void)'
29
 *      'void scrollback(int lines)'                    *
30
 *      'void scrollfront(int lines)'                   *
31
 *      'int do_screendump(int arg)'
32
 *
33
 *      'int con_get_font(char *)'
34
 *      'int con_set_font(char *)'
35
 *      'int con_get_trans(char *)'
36
 *      'int con_set_trans(char *)'
37
 *
38
 *      'int mouse_reporting(void)'
39
 */
40
 
41
#define BLANK 0x0020
42
 
43
/* A bitmap for codes <32. A bit of 1 indicates that the code
44
 * corresponding to that bit number invokes a special action
45
 * (such as cursor movement) and should not be displayed as a
46
 * glyph unless the disp_ctrl mode is explicitly enabled.
47
 */
48
#define CTRL_ACTION 0x0d00ff81
49
#define CTRL_ALWAYS 0x0800f501  /* Cannot be overriden by disp_ctrl */
50
 
51
/*
52
 * Here is the default bell parameters: 750HZ, 1/8th of a second
53
 */
54
#define DEFAULT_BELL_PITCH      750
55
#define DEFAULT_BELL_DURATION   (HZ/8)
56
 
57
/*
58
 *  NOTE!!! We sometimes disable and enable interrupts for a short while
59
 * (to put a word in video IO), but this will work even for keyboard
60
 * interrupts. We know interrupts aren't enabled when getting a keyboard
61
 * interrupt, as we use trap-gates. Hopefully all is well.
62
 */
63
 
64
#include <linux/config.h>
65
#include <linux/sched.h>
66
#include <linux/timer.h>
67
#include <linux/interrupt.h>
68
#include <linux/tty.h>
69
#include <linux/tty_flip.h>
70
#include <linux/kernel.h>
71
#include <linux/errno.h>
72
#include <linux/kd.h>
73
#include <linux/major.h>
74
#include <linux/malloc.h>
75
#include <linux/mm.h>
76
 
77
#include <asm/io.h>
78
#include <asm/segment.h>
79
#include <asm/irq.h>
80
#include <asm/hardware.h>
81
 
82
#define DEBUG
83
 
84
#include "kbd_kern.h"
85
#include "consolemap.h"
86
#include "vt_kern.h"
87
#include "selection.h"
88
 
89
#define set_kbd(x) set_vc_kbd_mode (vt->kbd, x)
90
#define clr_kbd(x) clr_vc_kbd_mode (vt->kbd, x)
91
#define is_kbd(x)  vc_kbd_mode (vt->kbd, x)
92
 
93
#define decarm          VC_REPEAT
94
#define decckm          VC_CKMODE
95
#define kbdapplic       VC_APPLIC
96
#define lnm             VC_CRLF
97
 
98
/*
99
 * this is what the terminal answers to a ESC-Z or csi0c query.
100
 */
101
#define VT100ID "\033[?1;2c"
102
#define VT102ID "\033[?6c"
103
 
104
extern int setup_arm_irq(int, struct irqaction *);
105
 
106
/*
107
 * routines to load custom translation table, EGA/VGA font and
108
 * VGA colour palette from console.c
109
 */
110
extern int con_set_trans_old(unsigned char * table);
111
extern int con_get_trans_old(unsigned char * table);
112
extern int con_set_trans_new(unsigned short * table);
113
extern int con_get_trans_new(unsigned short * table);
114
extern void con_clear_unimap(struct unimapinit *ui);
115
extern int con_set_unimap(ushort ct, struct unipair *list);
116
extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list);
117
extern void con_set_default_unimap(void);
118
extern int con_set_font(char * fontmap);
119
extern int con_get_font(char * fontmap);
120
 
121
 
122
/* ARM Extensions */
123
#if defined(HAS_VIDC)
124
 
125
extern void memc_write (int reg, int val);
126
extern void vidc_write (int reg, int val);
127
static int __r;
128
#define palette_setpixel(p) __r = p
129
#define palette_write(v)                        \
130
{                                               \
131
  int rr = __r++, red, green, blue, vv = (v);   \
132
  red   = (vv >> 4)  & 0x00f;                   \
133
  green = (vv >> 8)  & 0x0f0;                   \
134
  blue  = (vv >> 12) & 0xf00;                   \
135
  outl((rr<<26)|red|green|blue, IO_VIDC_BASE);  \
136
}
137
 
138
#define MAX_PIX 16
139
 
140
#elif defined(HAS_VIDC20)
141
#define palette_setpixel(p)     outl(0x10000000|((p) & 255), IO_VIDC_BASE)
142
#define palette_write(v)        outl(0x00000000|((v) & 0x00ffffff), IO_VIDC_BASE)
143
#define MAX_PIX 256
144
#endif
145
 
146
/*
147
 * from ll_wr_char.S
148
 */
149
int bytes_per_char_h, bytes_per_char_v, video_size_row;
150
extern void ll_write_char(unsigned long ps, unsigned long chinfo);
151
extern unsigned long con_charconvtable[256];
152
extern unsigned long map_screen_mem (unsigned long vid_base, unsigned long kmem, int remap);
153
#include <linux/ctype.h>
154
 
155
extern struct console_driver screen_driver, buffer_driver;
156
 
157
#ifndef MIN
158
#define MIN(a,b)        ((a) < (b) ? (a) : (b))
159
#endif
160
 
161
static void gotoxy (struct con_struct *vcd, int new_x, int new_y);
162
static inline void set_cursor (const struct vt * const vt);
163
extern void reset_vc(const struct vt * const vt);
164
extern void register_console(void (*proc)(const char *));
165
extern void compute_shiftstate(void);
166
extern void con_reset_palette (const struct vt * const vt);
167
extern void con_set_palette (const struct vt * const vt);
168
 
169
static int printable;                           /* Is console ready for printing? */
170
 
171
#define console_charmask 0xff
172
#ifndef console_charmask
173
static unsigned short console_charmask = 0x0ff;
174
#endif
175
 
176
#include "font.h"
177
 
178
static const unsigned long palette_1[MAX_PIX] = {
179
        0x00000000,             /* Black   */
180
        0x00ffffff,             /* White   */
181
        0x00000000              /* Black   */
182
};
183
 
184
static const unsigned long palette_4[MAX_PIX] = {
185
        0x00000000,             /* Black   */
186
        0x000000cc,             /* Red     */
187
        0x0000cc00,             /* Green   */
188
        0x0000cccc,             /* Yellow  */
189
        0x00cc0000,             /* Blue    */
190
        0x00cc00cc,             /* Magenta */
191
        0x00cccc00,             /* Cyan    */
192
        0x00cccccc,             /* White   */
193
        0x00000000,
194
        0x000000ff,
195
        0x0000ff00,
196
        0x0000ffff,
197
        0x00ff0000,
198
        0x00ff00ff,
199
        0x00ffff00,
200
        0x00ffffff
201
};
202
 
203
#if defined(HAS_VIDC)
204
static const unsigned long palette_8[MAX_PIX] = {
205
        0x00000000,
206
        0x00111111,
207
        0x00222222,
208
        0x00333333,
209
        0x00440000,
210
        0x00551111,
211
        0x00662222,
212
        0x00773333,
213
        0x00000044,
214
        0x00111155,
215
        0x00222266,
216
        0x00333377,
217
        0x00440044,
218
        0x00551155,
219
        0x00662266,
220
        0x00773377
221
};
222
#elif defined(HAS_VIDC20)
223
#define palette_8 palette_4
224
#endif
225
 
226
static const unsigned long *default_palette_entries = palette_4;
227
 
228
static const unsigned char color_1[] = {0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 };
229
static const unsigned char color_4[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 };
230
#if defined(HAS_VIDC)
231
static const unsigned char color_8[] = {0x00, 0x18, 0x60, 0x78, 0x84, 0x9C, 0xE4, 0xFC,
232
                                        0x00, 0x1B, 0x63, 0x7B, 0x87, 0x9F, 0xE7, 0xFF};
233
#elif defined(HAS_VIDC20)
234
static const unsigned char color_8[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 };
235
#endif
236
static const unsigned char *color_table = color_4;
237
 
238
/*===================================================================================*/
239
 
240
#ifdef CONFIG_SERIAL_ECHO
241
#include "serialecho.c"
242
#endif
243
 
244
/*
245
 * functions to handle /dev/fb
246
 */
247
int con_fb_read(char *buf, unsigned long pos, int count)
248
{
249
        return -EIO;
250
}
251
 
252
int con_fb_write(const char *buf, unsigned long pos, int count)
253
{
254
        return -EIO;
255
}
256
 
257
int con_fb_mmap(unsigned long vma_start, unsigned long vma_offset,
258
                        unsigned long vma_end, pgprot_t prot)
259
{
260
        if (vma_offset > vtdata.screen.memsize ||
261
            vma_end - vma_start + vma_offset > vtdata.screen.memsize)
262
                return -EINVAL;
263
        return remap_page_range(vma_start, SCREEN2_BASE + vma_offset,
264
                                vma_end - vma_start, prot);
265
}
266
 
267
#ifdef DEBUG
268
static int vcd_validate (struct con_struct *vcd, const char *msg)
269
{
270
    unsigned long old_scrorigin, old_scrpos, old_buforigin, old_bufpos, w = 0;
271
 
272
    old_scrorigin = vcd->screen.origin;
273
    old_scrpos = vcd->screen.pos;
274
    old_buforigin = vtdata.buffer.origin;
275
    old_bufpos = vcd->buffer.pos;
276
    if (vcd->screen.origin < SCREEN1_BASE || vcd->screen.origin > SCREEN1_END) {
277
        vcd->screen.origin = SCREEN2_BASE;
278
        w = 1;
279
    }
280
    if (vcd->screen.pos < SCREEN1_BASE || vcd->screen.pos > SCREEN2_END) {
281
        vcd->screen.pos = SCREEN2_BASE;
282
        w = 1;
283
    }
284
 
285
    if (w)
286
        printk ("*** CONSOLE ERROR: %s: (%p): origin = %08lX pos = %08lX ***\n",
287
                                msg, vcd, old_scrorigin, old_scrpos);
288
    return w;
289
}
290
#endif
291
 
292
void no_scroll(char *str, int *ints)
293
{
294
}
295
 
296
static unsigned long __origin;          /* Offset of currently displayed screen */
297
 
298
static void __set_origin(unsigned long offset)
299
{
300
        unsigned long flags;
301
 
302
        clear_selection ();
303
 
304
        offset = offset - vtdata.screen.memstart;
305
        if (offset >= vtdata.screen.memsize)
306
                offset -= vtdata.screen.memsize;
307
 
308
        save_flags_cli (flags);
309
        __origin = offset;
310
        video_set_dma(0, vtdata.screen.memsize, offset);
311
        restore_flags(flags);
312
}
313
 
314
void scrollback(int lines)
315
{
316
}
317
 
318
void scrollfront(int lines)
319
{
320
}
321
 
322
void scroll_set_origin (unsigned long offset)
323
{
324
        __set_origin(offset);
325
}
326
 
327
static void set_origin (const struct vt * const vt)
328
{
329
        if (vtdata.fgconsole != vt || vt->vtd->vc_mode == KD_GRAPHICS)
330
                return;
331
        __set_origin(vt->vcd->screen.origin);
332
}
333
 
334
/* -------------------------------------------------------------------------------
335
 * Cursor
336
 * ------------------------------------------------------------------------------- */
337
 
338
static char cursor_on = 0;
339
static unsigned long cp;
340
 
341
static void put_cursor(char on_off,unsigned long newcp)
342
{
343
        static char con;
344
        unsigned long cp_p = cp;
345
        int c = vtdata.screen.bytespercharh == 8 ? color_table[15] : 0x11 * color_table[15];
346
        int i;
347
 
348
        if (vtdata.fgconsole->vtd->vc_mode == KD_GRAPHICS)
349
                return;
350
 
351
        cp = newcp;
352
 
353
        if (con != on_off) {
354
                if (cp_p != -1)
355
                        for (i = 0; i < vtdata.screen.bytespercharh; i++)
356
                                ((unsigned char*)cp_p)[i]^=c;
357
                con = on_off;
358
        }
359
}
360
 
361
static void vsync_irq(int irq, void *dev_id, struct pt_regs *regs)
362
{
363
        static char cursor_flash = 16;
364
 
365
        if (!--cursor_flash) {
366
                cursor_flash = 16;
367
                cursor_on = cursor_on ? 0 : 1;
368
                if (vtdata.fgconsole->vcd->screen.cursoron > 0)
369
                        put_cursor(cursor_on,cp);
370
        }
371
}
372
 
373
static void hide_cursor(void)
374
{
375
        put_cursor (0, -1);
376
}
377
 
378
static void set_cursor (const struct vt * const vt)
379
{
380
        unsigned long flags;
381
 
382
        if (vt != vtdata.fgconsole || vt->vtd->vc_mode == KD_GRAPHICS)
383
                return;
384
 
385
        save_flags_cli (flags);
386
        if (vt->vcd->deccm) {
387
#ifdef DEBUG
388
                vcd_validate (vt->vcd, "set_cursor");
389
#endif
390
                cp = vt->vcd->screen.pos + vtdata.numcolumns *
391
                        vtdata.screen.bytespercharh * (vtdata.screen.bytespercharv - 1);
392
        } else
393
                hide_cursor();
394
        restore_flags(flags);
395
}
396
 
397
static void vcd_removecursors (const struct vt *vt)
398
{
399
        unsigned long flags;
400
 
401
        save_flags_cli (flags);
402
 
403
        if (--vt->vcd->screen.cursoron == 0 && vtdata.fgconsole == vt)
404
                put_cursor (0, cp);
405
 
406
        restore_flags (flags);
407
}
408
 
409
static void vcd_restorecursors(const struct vt *vt)
410
{
411
        unsigned long flags;
412
 
413
        save_flags_cli (flags);
414
 
415
        if (++vt->vcd->screen.cursoron == 1 && cursor_on && vtdata.fgconsole == vt)
416
                put_cursor (1, cp);
417
 
418
        restore_flags (flags);
419
}
420
 
421
/* -----------------------------------------------------------------------------------------
422
 * VC stuff
423
 * ----------------------------------------------------------------------------------------- */
424
/*
425
 * gotoxy() must verify all boundaries, because the arguments
426
 * might also be negative. If a given position is out of
427
 * bounds, the cursor is placed at the nearest margin.
428
 */
429
static void gotoxy (struct con_struct *vcd, int new_x, int new_y)
430
{
431
    int min_y, max_y;
432
 
433
    if (new_x < 0)
434
        vcd->curstate.x = 0;
435
    else
436
    if (new_x >= vtdata.numcolumns)
437
        vcd->curstate.x = vtdata.numcolumns - 1;
438
    else
439
        vcd->curstate.x = new_x;
440
 
441
    if (vcd->decom) {
442
        new_y += vcd->top;
443
        min_y = vcd->top;
444
        max_y = vcd->bottom;
445
    } else {
446
        min_y = 0;
447
        max_y = vtdata.numrows;
448
    }
449
 
450
    if (new_y < min_y)
451
        vcd->curstate.y = min_y;
452
    else if (new_y >= max_y)
453
        vcd->curstate.y = max_y - 1;
454
    else
455
        vcd->curstate.y = new_y;
456
 
457
    vcd->driver.gotoxy (vcd);
458
    vcd->need_wrap = 0;
459
#ifdef DEBUG
460
    vcd_validate (vcd, "gotoxy");
461
#endif
462
}
463
 
464
/* for absolute user moves, when decom is set */
465
static void gotoxay (struct con_struct *vcd, int new_x, int new_y)
466
{
467
    gotoxy(vcd, new_x, vcd->decom ? (vcd->top+new_y) : new_y);
468
}
469
 
470
static void update_attr (const struct vt * const vt)
471
{
472
    unsigned int backcol, forecol;
473
 
474
    backcol = color_table[vt->vcd->curstate.backcol];
475
    if (vt->vcd->curstate.flags & FLG_BOLD)
476
        forecol = color_table[vt->vcd->curstate.forecol + 8];
477
    else
478
        forecol = color_table[vt->vcd->curstate.forecol];
479
    vt->vcd->combined_state = (vt->vcd->curstate.flags << 24) |
480
                              (backcol << 16) |
481
                              (forecol << 8);
482
    switch (vtdata.screen.bitsperpix) {
483
    case 1:
484
        vt->vcd->cached_backcolwrd = 0;
485
        break;
486
    default:
487
    case 4:
488
        vt->vcd->cached_backcolwrd = 0x11111111 * backcol;
489
        break;
490
    case 8:
491
        vt->vcd->cached_backcolwrd = 0x01010101 * backcol;
492
        break;
493
    }
494
}
495
 
496
static void default_attr (const struct vt * const vt)
497
{
498
    vt->vcd->curstate.flags &= ~(FLG_INVERSE|FLG_FLASH|FLG_UNDERLINE|FLG_ITALIC|FLG_BOLD);
499
    vt->vcd->curstate.forecol = vt->vcd->def_forecol;
500
    vt->vcd->curstate.backcol = vt->vcd->def_backcol;
501
}
502
 
503
static int csi_m (const struct vt * const vt)
504
{
505
    struct con_struct *vcd = vt->vcd;
506
    int i, ret = 0;
507
 
508
    for (i = 0; i <= vcd->npar; i++) {
509
        switch (vcd->par[i]) {
510
        case 0:
511
            default_attr (vt);
512
            break;
513
        case 1:
514
            vcd->curstate.flags |= FLG_BOLD;
515
            break;      /* Bold */
516
        case 2:
517
            vcd->curstate.flags &= ~FLG_BOLD;
518
            break;      /* Feint */
519
        case 3:
520
            vcd->curstate.flags |= FLG_ITALIC;
521
            break;      /* Italic */
522
        case 4:
523
            vcd->curstate.flags |= FLG_UNDERLINE;
524
            break;      /* Underline */
525
        case 5:
526
        case 6:
527
            vcd->curstate.flags |= FLG_FLASH;
528
            break;      /* Flash */
529
        case 7:
530
            vcd->curstate.flags |= FLG_INVERSE;
531
            break;      /* Inverse chars */
532
 
533
        case 10:
534
            /* ANSI X3.64-1979 (SCO-ish?)
535
             * Select primary font, don't display
536
             * control chars if defined, don't set
537
             * bit 8 on output.
538
             */
539
            vcd->translate = set_translate(vcd->curstate.flags & FLG_CHRSET
540
                                ? vcd->curstate.G1_charset
541
                                : vcd->curstate.G0_charset);
542
            vcd->disp_ctrl = 0;
543
            vcd->toggle_meta = 0;
544
            ret = 1;
545
            break;
546
        case 11:
547
            /* ANSI X3.64-1979 (SCO-ish?)
548
             * Select first alternate font, let's
549
             * chars < 32 be displayed as ROM chars.
550
             */
551
            vcd->translate = set_translate(IBMPC_MAP);
552
            vcd->disp_ctrl = 1;
553
            vcd->toggle_meta = 0;
554
            ret = 1;
555
            break;
556
        case 12:
557
            /* ANSI X3.64-1979 (SCO-ish?)
558
             * Select second alternate font, toggle
559
             * high bit before displaying as ROM char.
560
             */
561
            vcd->translate = set_translate(IBMPC_MAP);
562
            vcd->disp_ctrl = 1;
563
            vcd->toggle_meta = 1;
564
            ret = 1;
565
            break;
566
        case 21:
567
        case 22:
568
            vcd->curstate.flags &= ~FLG_BOLD;
569
            break;
570
        case 24:
571
            vcd->curstate.flags &= ~FLG_UNDERLINE;
572
            break;
573
        case 25:
574
            vcd->curstate.flags &= ~FLG_FLASH;
575
            break;
576
        case 27:
577
            vcd->curstate.flags &= ~FLG_INVERSE;
578
            break;
579
        case 30:
580
        case 31:
581
        case 32:
582
        case 33:
583
        case 34:
584
        case 35:
585
        case 36:
586
        case 37:
587
            vcd->curstate.forecol = vcd->par[i]-30;
588
            break;                                              /* Foreground colour */
589
        case 38:
590
            vcd->curstate.forecol = vcd->def_forecol;
591
            vcd->curstate.flags &= ~FLG_UNDERLINE;
592
            break;
593
        case 39:
594
            vcd->curstate.forecol = vcd->def_forecol;
595
            vcd->curstate.flags &= ~FLG_UNDERLINE;
596
            break;                                              /* Default foreground colour */
597
        case 40:
598
        case 41:
599
        case 42:
600
        case 43:
601
        case 44:
602
        case 45:
603
        case 46:
604
        case 47:
605
            vcd->curstate.backcol = vcd->par[i]-40;
606
            break;                                              /* Background colour */
607
        case 49:
608
            vcd->curstate.backcol = vcd->def_backcol;
609
            break;                                              /* Default background colour */
610
        }
611
    }
612
    update_attr (vt);
613
    return ret;
614
}
615
 
616
static void respond_string (char *p, struct tty_struct *tty)
617
{
618
    while (*p)
619
        tty_insert_flip_char (tty, *p++, 0);
620
    tty_schedule_flip (tty);
621
}
622
 
623
static void cursor_report (const struct vt *vt)
624
{
625
    char buf[40];
626
 
627
    sprintf (buf, "\033[%d;%dR", vt->vcd->curstate.y + (vt->vcd->decom ? vt->vcd->top + 1 : 1),
628
                                     vt->vcd->curstate.x + 1);
629
    respond_string (buf, *vt->tty);
630
}
631
 
632
static void status_report (struct tty_struct *tty)
633
{
634
    respond_string ("\033[0n", tty);
635
}
636
 
637
static void respond_ID (struct tty_struct *tty)
638
{
639
    respond_string(VT102ID, tty);
640
}
641
 
642
void mouse_report (struct tty_struct *tty, int butt, int mrx, int mry)
643
{
644
    char buf[8];
645
 
646
    sprintf (buf,"\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
647
        (char)('!'+mry));
648
    respond_string(buf, tty);
649
}
650
 
651
/* invoked by ioctl(TIOCLINUX) */
652
int mouse_reporting (void)
653
{
654
    return vtdata.fgconsole->vcd->report_mouse;
655
}
656
 
657
static inline unsigned long screenpos (const struct vt * const vt, int offset)
658
{
659
    int hx, hy;
660
 
661
    hx = offset % vtdata.numcolumns;
662
    hy = offset / vtdata.numcolumns;
663
    return vt->vcd->screen.origin + hy * vtdata.screen.sizerow + hx * vtdata.screen.bytespercharh;
664
}
665
 
666
void invert_screen (const struct vt * const vt, unsigned int offset, unsigned int count)
667
{
668
    struct con_struct *vcd = vt->vcd;
669
    unsigned long *buffer = vcd->driver.buffer_pos(vcd, offset);
670
    unsigned long p, pp;
671
    int i;
672
 
673
    for (i = 0; i <= count; i++)
674
        buffer[i] ^= FLG_INVERSE << 24;
675
 
676
    if (vt == vtdata.fgconsole) {
677
        int hx, hy, hex, hey;
678
 
679
        hx = offset % vtdata.numcolumns;
680
        hy = offset / vtdata.numcolumns;
681
        hex = (offset + count) % vtdata.numcolumns;
682
        hey = (offset + count) / vtdata.numcolumns;
683
 
684
        p = vcd->screen.origin + hy * vtdata.screen.sizerow;
685
        pp = p + hx * vtdata.screen.bytespercharh;
686
        for (;hy <= hey; hy ++) {
687
            for (; hx < ((hy == hey) ? hex + 1 : vtdata.numcolumns); hx ++) {
688
                ll_write_char (pp, *buffer++);
689
                pp += vtdata.screen.bytespercharh;
690
            }
691
            hx = 0;
692
            pp = p += vtdata.screen.sizerow;
693
        }
694
    }
695
}
696
 
697
void complement_pos (const struct vt * const vt, unsigned int offset)
698
{
699
    static unsigned long old = 0;
700
    static unsigned long p = 0;
701
    unsigned long complement;
702
 
703
    switch (vtdata.screen.bitsperpix) {
704
    case 4:
705
        complement = 0x00070700;
706
        break;
707
    case 8:
708
#ifndef HAS_VIDC20
709
        complement = 0x00fcfc00;
710
#else
711
        complement = 0x00070700;
712
#endif
713
        break;
714
    default:
715
        complement = 0;
716
    }
717
 
718
    if (p)
719
        ll_write_char (p, old);
720
    if ((int)offset == -1)
721
        p = 0;
722
    else {
723
        old = *vt->vcd->driver.buffer_pos(vt->vcd, offset);
724
        p = screenpos (vt, offset);
725
        ll_write_char (p, old ^ complement);
726
    }
727
}
728
 
729
unsigned long screen_word (const struct vt * const vt, unsigned int offset)
730
{
731
    return *vt->vcd->driver.buffer_pos (vt->vcd, offset);
732
}
733
 
734
int scrw2glyph (unsigned long scr_word)
735
{
736
    return scr_word & 255;
737
}
738
 
739
unsigned long *screen_pos (const struct vt * const vt, unsigned int offset)
740
{
741
    return vt->vcd->driver.buffer_pos (vt->vcd, offset);
742
}
743
 
744
void getconsxy (const struct vt * const vt, char *p)
745
{
746
    p[0] = vt->vcd->curstate.x;
747
    p[1] = vt->vcd->curstate.y;
748
}
749
 
750
void putconsxy (const struct vt * const vt, char *p)
751
{
752
    gotoxy (vt->vcd, p[0], p[1]);
753
    set_cursor (vt);
754
}
755
 
756
static void csi_J (const struct vt * const vt, int vpar);
757
 
758
static void set_mode (const struct vt * const vt, int on_off)
759
{
760
    struct con_struct *vcd = vt->vcd;
761
    int i;
762
 
763
    for (i = 0; i <= vcd->npar; i++)
764
        if (vcd->ques)
765
            switch(vcd->par[i]) {       /* DEC private modes set/reset */
766
            case 1:                     /* Cursor keys send ^[Ox/^[[x */
767
                if (on_off)
768
                    set_kbd(decckm);
769
                else
770
                    clr_kbd(decckm);
771
                break;
772
            case 3:             /* 80/132 mode switch unimplemented */
773
                vcd->deccolm = on_off;
774
                csi_J (vt, 2);
775
                gotoxy (vcd, 0, 0);
776
                break;
777
            case 5:             /* Inverted screen on/off */
778
                if (vcd->decscnm != on_off) {
779
                    vcd->decscnm = on_off;
780
                    invert_screen (vt, 0, vtdata.buffer.totsize);
781
                    update_attr (vt);
782
                }
783
                break;
784
            case 6:             /* Origin relative/absolute */
785
                vcd->decom = on_off;
786
                gotoxay (vcd, 0, 0);
787
                break;
788
            case 7:             /* Autowrap on/off */
789
                vcd->decawm = on_off;
790
                break;
791
            case 8:             /* Autorepeat on/off */
792
                if (on_off)
793
                    set_kbd(decarm);
794
                else
795
                    clr_kbd(decarm);
796
                break;
797
            case 9:
798
                vcd->report_mouse = on_off ? 1 : 0;
799
                break;
800
            case 25:            /* Cursor on/off */
801
                vcd->deccm = on_off;
802
                set_cursor (vt);
803
                break;
804
            case 1000:
805
                vcd->report_mouse = on_off ? 2 : 0;
806
                break;
807
            }
808
        else
809
            switch(vcd->par[i]) {       /* ANSI modes set/reset */
810
            case 3:                     /* Monitor (display ctrls) */
811
                vcd->disp_ctrl = on_off;
812
                break;
813
            case 4:                     /* Insert mode on/off */
814
                vcd->decim = on_off;
815
                break;
816
            case 20:                    /* Lf, Enter = CrLf/Lf */
817
                if (on_off)
818
                    set_kbd(lnm);
819
                else
820
                    clr_kbd(lnm);
821
                break;
822
            }
823
}
824
 
825
static void setterm_command (const struct vt * const vt)
826
{
827
        struct con_struct *vcd = vt->vcd;
828
        switch (vt->vcd->par[0]) {
829
                case 1: /* Set colour for underline mode (implemented as an underline) */
830
                case 2: /* set colour for half intensity mode (unimplemented) */
831
                        break;
832
                case 8:
833
                        vcd->def_forecol = vcd->curstate.forecol;
834
                        vcd->def_backcol = vcd->curstate.backcol;
835
                        break;
836
                case 9:
837
                        vtdata.screen.blankinterval =
838
                                ((vcd->par[1] < 60) ? vcd->par[1] : 60) * 60 * HZ;
839
                        vt_pokeblankedconsole ();
840
                        break;
841
                case 10: /* set bell frequency in Hz */
842
                        if (vcd->npar >= 1)
843
                                vcd->bell_pitch = vcd->par[1];
844
                        else
845
                                vcd->bell_pitch = DEFAULT_BELL_PITCH;
846
                        break;
847
                case 11: /* set bell duration in msec */
848
                        if (vcd->npar >= 1)
849
                                vcd->bell_duration = (vcd->par[1] < 2000) ?
850
                                        vcd->par[1]*HZ/1000 : 0;
851
                        else
852
                                vcd->bell_duration = DEFAULT_BELL_DURATION;
853
                        break;
854
                case 12: { /* bring specified console to the front */
855
                        int arg = vcd->par[1];
856
                        if (arg >= 1 && vt_allocated(vt_con_data + (arg - 1) ))
857
                                vt_updatescreen(vt_con_data + (arg - 1));
858
                        break;
859
                        }
860
                case 13: /* unblank the screen */
861
                        vt_do_unblankscreen ();
862
                        break;
863
                case 14: /* set vesa powerdown interval */
864
#if todo
865
                        vesa_off_interval = ((vcd->par[1] < 60) ? vcd->par[1] : 60) * 60 * HZ;
866
#endif
867
                        break;
868
        }
869
}
870
 
871
static void csi_J (const struct vt * const vt, int vpar)
872
{
873
    unsigned char endx, endy;
874
    unsigned char startx, starty;
875
 
876
    switch (vpar) {
877
    case 0: /* erase from cursor to bottom of screen (including char at (x, y) */
878
        startx = vt->vcd->curstate.x;
879
        starty = vt->vcd->curstate.y;
880
        endx   = vtdata.numcolumns - 1;
881
        endy   = vtdata.numrows - 1;
882
        break;
883
    case 1: /* erase from top of screen to cursor (including char at (x, y) */
884
        startx = 0;
885
        starty = 0;
886
        endx   = vt->vcd->curstate.x;
887
        endy   = vt->vcd->curstate.y;
888
        break;
889
    case 2: /* erase entire screen */
890
        startx = 0;
891
        starty = 0;
892
        endx   = vtdata.numcolumns - 1;
893
        endy   = vtdata.numrows - 1;
894
#if TODO
895
        origin = video_mem_base;
896
        set_origin (currcons);
897
        gotoxy (currcons, x, y);
898
#endif
899
        break;
900
    default:
901
        return;
902
    }
903
    vt->vcd->driver.erase (vt->vcd, startx, starty, endx, endy);
904
    /*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
905
}
906
 
907
static void csi_K (const struct vt * const vt, int vpar)
908
{
909
    unsigned char endx;
910
    unsigned char startx;
911
 
912
    switch(vpar) {
913
    case 0: /* erase from cursor to end of line */
914
        startx = vt->vcd->curstate.x;
915
        endx   = vtdata.numcolumns - 1;
916
        break;
917
    case 1: /* erase from beginning of line to cursor */
918
        startx = 0;
919
        endx   = vt->vcd->curstate.x;
920
        break;
921
    case 2: /* erase entire line */
922
        startx = 0;
923
        endx   = vtdata.numcolumns - 1;
924
        break;
925
    default:
926
        return;
927
    }
928
    vt->vcd->driver.erase(vt->vcd, startx, vt->vcd->curstate.y, endx, vt->vcd->curstate.y);
929
    /*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
930
}
931
 
932
static void csi_X (const struct vt * const vt, int vpar) /* erase the following vpar positions */
933
{                                                        /* not vt100? */
934
    unsigned char countx, county;
935
    unsigned char startx, starty;
936
 
937
    if (!vpar)
938
        vpar++;
939
 
940
    startx = vt->vcd->curstate.x;
941
    starty = vt->vcd->curstate.y;
942
    countx = 0;
943
    county = 0;
944
#if TODO
945
    vt->vcd->driver.erase(vt->vcd,startx,starty,countx,county);
946
#endif
947
    /*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
948
}
949
 
950
static void csi_at (const struct vt * const vt, int nr)
951
{
952
    if (nr > vtdata.numcolumns - vt->vcd->curstate.x)
953
        nr = vtdata.numcolumns - vt->vcd->curstate.x;
954
    else if (!nr)
955
        nr = 1;
956
    vt->vcd->driver.insert_char(vt->vcd, nr);
957
}
958
 
959
static void csi_L (const struct vt * const vt, int nr)
960
{
961
    if (nr > vtdata.numrows - vt->vcd->curstate.y)
962
        nr = vtdata.numrows - vt->vcd->curstate.y;
963
    else if (!nr)
964
        nr = 1;
965
    vt->vcd->driver.scroll_down (vt->vcd, vt->vcd->curstate.y, vt->vcd->bottom, nr);
966
/*  vt->vcd->need_wrap = 0; why? We haven't moved the cursor. */
967
}
968
 
969
static void csi_P (const struct vt * const vt, int nr)
970
{
971
    if (nr > vtdata.numcolumns)
972
        nr = vtdata.numcolumns;
973
    else if (!nr)
974
        nr = 1;
975
    vt->vcd->driver.delete_char(vt->vcd, nr);
976
}
977
 
978
static void csi_M (const struct vt * const vt, int nr)
979
{
980
    if (nr > vtdata.numrows)
981
        nr = vtdata.numrows;
982
    else if (!nr)
983
        nr = 1;
984
    vt->vcd->driver.scroll_up (vt->vcd, vt->vcd->curstate.y, vt->vcd->bottom, nr);
985
/*  vt->vcd->need_wrap = 0; why? we haven't moved the cursor. */
986
}
987
 
988
enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
989
        EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
990
        ESpalette };
991
 
992
static void reset_terminal (const struct vt * const vt, int initialising)
993
{
994
    struct con_struct *vcd;
995
 
996
    vcd = vt->vcd;
997
 
998
    vcd->top                    = 0;
999
    vcd->bottom                 = vtdata.numrows;
1000
    vcd->state                  = ESnormal;
1001
    vcd->ques                   = 0;
1002
    vcd->translate              = set_translate (LAT1_MAP);
1003
    vcd->curstate.G0_charset    = LAT1_MAP;
1004
    vcd->curstate.G1_charset    = GRAF_MAP;
1005
    vcd->curstate.flags         = 0;
1006
    vcd->need_wrap              = 0;
1007
    vcd->report_mouse           = 0;
1008
    vcd->utf                    = 0;
1009
    vcd->utf_count              = 0;
1010
    vcd->disp_ctrl              = 0;
1011
    vcd->toggle_meta            = 0;
1012
    vcd->decscnm                = 0;
1013
    vcd->decom                  = 0;
1014
    vcd->decawm                 = 1;
1015
    vcd->deccm                  = 1;
1016
    vcd->decim                  = 0;
1017
    vcd->curstate.forecol       = 7;
1018
    vcd->curstate.backcol       = 0;
1019
    vcd->def_forecol            = 7;
1020
    vcd->def_backcol            = 0;
1021
    vcd->tab_stop[0]             = 0x01010100;
1022
    vcd->tab_stop[1]            =
1023
    vcd->tab_stop[2]            =
1024
    vcd->tab_stop[3]            =
1025
    vcd->tab_stop[4]            = 0x01010101;
1026
 
1027
    set_kbd (decarm);
1028
    clr_kbd (decckm);
1029
    clr_kbd(kbdapplic);
1030
    clr_kbd(lnm);
1031
 
1032
    vt->kbd->lockstate          = 0;
1033
    vt->kbd->ledmode            = LED_SHOW_FLAGS;
1034
    vt->kbd->ledflagstate       = vt->kbd->default_ledflagstate;
1035
    if (!initialising)
1036
        set_leds ();
1037
 
1038
    if (vcd->screen.palette_entries) {
1039
        kfree (vcd->screen.palette_entries);
1040
        vcd->screen.palette_entries = 0;
1041
    }
1042
 
1043
    gotoxy (vcd, 0, 0);
1044
    vcd->savedstate = vcd->curstate;
1045
    update_attr (vt);
1046
 
1047
    if (!initialising)
1048
        csi_J (vt, 2);
1049
}
1050
 
1051
 
1052
static inline void update_palette(const struct vt * const vt)
1053
{
1054
        const unsigned long *palette_entries;
1055
        int i;
1056
 
1057
        if (vt->vcd->screen.palette_entries || vt->vtd->vc_mode != KD_GRAPHICS)
1058
                palette_entries = default_palette_entries;
1059
        else
1060
                palette_entries = vt->vcd->screen.palette_entries;
1061
 
1062
        palette_setpixel(0);
1063
        for (i = MAX_PIX; i > 3; i -= 4) {
1064
                palette_write(*palette_entries++);
1065
                palette_write(*palette_entries++);
1066
                palette_write(*palette_entries++);
1067
                palette_write(*palette_entries++);
1068
        }
1069
        for (; i > 0; i--)
1070
                palette_write(*palette_entries++);
1071
}
1072
 
1073
void update_scrmem (const struct vt * const vt, int start, int length)
1074
{
1075
        unsigned long p, pp, sx, sy, ex, ey;
1076
        unsigned long *buffer;
1077
 
1078
        length += start;
1079
        sy = start / vtdata.numcolumns;
1080
        sx = start % vtdata.numcolumns;
1081
        ey = length / vtdata.numcolumns;
1082
        ex = length % vtdata.numcolumns;
1083
 
1084
        if (ey > vtdata.numrows)
1085
                ey = vtdata.numrows;
1086
 
1087
        p = vt->vcd->screen.origin + sy * vtdata.screen.sizerow;
1088
        buffer = vt->vcd->buffer.buffer + start;
1089
 
1090
        if (ey > sy) {
1091
                for (; sy < ey; sy++) {
1092
                        pp = p + sx * vtdata.screen.bytespercharh;
1093
                        for (; sx < vtdata.numcolumns; sx++) {
1094
                                ll_write_char (pp, *buffer++);
1095
                                pp += vtdata.screen.bytespercharh;
1096
                        }
1097
                        p += vtdata.screen.sizerow;
1098
                        sx = 0;
1099
                }
1100
        }
1101
 
1102
        if (ey == sy && ex) {
1103
                for (; sx < ex; sx++) {
1104
                        ll_write_char (p, *buffer++);
1105
                        p += vtdata.screen.bytespercharh;
1106
                }
1107
        }
1108
}
1109
 
1110
void set_scrmem (const struct vt * const vt, long offset)
1111
{
1112
    unsigned long p, pp, my, by;
1113
    unsigned long *buffer;
1114
 
1115
    p = vt->vcd->screen.origin;
1116
    buffer = vt->vcd->buffer.buffer;
1117
 
1118
    by = vtdata.screen.sizerow;
1119
    for (my = vtdata.numrows; my > 0; my--) {
1120
        int mx, bx = vtdata.screen.bytespercharh;
1121
        pp = p;
1122
        mx = vtdata.numcolumns;
1123
        while (mx > 8) {
1124
            mx -= 8;
1125
            ll_write_char (pp, *buffer++); pp += bx;
1126
            ll_write_char (pp, *buffer++); pp += bx;
1127
            ll_write_char (pp, *buffer++); pp += bx;
1128
            ll_write_char (pp, *buffer++); pp += bx;
1129
            ll_write_char (pp, *buffer++); pp += bx;
1130
            ll_write_char (pp, *buffer++); pp += bx;
1131
            ll_write_char (pp, *buffer++); pp += bx;
1132
            ll_write_char (pp, *buffer++); pp += bx;
1133
        }
1134
        while (mx > 0) {
1135
            mx -= 1;
1136
            ll_write_char (pp, *buffer++); pp += bx;
1137
        }
1138
        p += by;
1139
    }
1140
    pp = vt->vcd->screen.origin + vtdata.screen.memsize;
1141
    memsetl((unsigned long *)p, vt->vcd->cached_backcolwrd, pp - p);
1142
    update_palette(vt);
1143
}
1144
 
1145
/*
1146
 * PIO_FONT support
1147
 */
1148
int con_set_font (char *arg)
1149
{
1150
        return -EINVAL;
1151
}
1152
 
1153
int con_get_font (char *arg)
1154
{
1155
        return -EINVAL;
1156
}
1157
 
1158
void con_reset_palette (const struct vt * const vt)
1159
{
1160
}
1161
 
1162
void con_set_palette (const struct vt * const vt)
1163
{
1164
        update_palette(vt);
1165
}
1166
 
1167
/* == arm specific console code ============================================================== */
1168
 
1169
int do_screendump(int arg)
1170
{
1171
    char *buf = (char *)arg;
1172
    int l;
1173
    if (!suser())
1174
        return -EPERM;
1175
    l = verify_area (VERIFY_WRITE, buf, 2);
1176
    if (l)
1177
        return l;
1178
    return -ENOSYS;
1179
}
1180
 
1181
void vcd_disallocate (struct vt *vt)
1182
{
1183
        if (vt->vcd && vt->vcd->buffer.kmalloced) {
1184
                vfree (vt->vcd->buffer.buffer);
1185
                vt->vcd->buffer.buffer = NULL;
1186
                vt->vcd->buffer.kmalloced = 0;
1187
        }
1188
}
1189
 
1190
int vcd_resize(unsigned long lines, unsigned long cols)
1191
{/* TODO */
1192
        return -ENOMEM;
1193
}
1194
 
1195
void vcd_blankscreen(int nopowersave)
1196
{
1197
        unsigned int pix;
1198
 
1199
    /* DISABLE VIDEO */
1200
        palette_setpixel(0);
1201
        for (pix = 0; pix < MAX_PIX; pix++)
1202
                palette_write(0);
1203
}
1204
 
1205
void vcd_unblankscreen (void)
1206
{
1207
        update_palette(vtdata.fgconsole);
1208
}
1209
 
1210
static unsigned long old_origin;
1211
 
1212
void vcd_savestate (const struct vt *vt, int blanked)
1213
{
1214
    struct con_struct *vcd = vt->vcd;
1215
    clear_selection ();
1216
    vcd_removecursors (vt);
1217
    old_origin = vt->vcd->screen.origin;
1218
 
1219
    if (blanked)
1220
        vtdata.blanked = NULL;
1221
 
1222
    memcpy (vcd->buffer.buffer, vtdata.buffer.buffer + vtdata.buffer.origin,
1223
                vtdata.buffer.totsize << 2);
1224
    vcd->buffer.pos -= vtdata.buffer.origin;
1225
    vcd->driver = buffer_driver;
1226
#ifdef DEBUG
1227
    vcd_validate (vt->vcd, "vcd_savestate");
1228
#endif
1229
}
1230
 
1231
void vcd_restorestate (const struct vt *vt)
1232
{
1233
    struct con_struct *vcd = vt->vcd;
1234
    int text_mode;
1235
    /*
1236
     * Reset the origin on this VT to be the same as the previous.
1237
     * This way we don't get any jumps when we change VT's.
1238
     */
1239
    text_mode = vt->vtd->vc_mode == KD_TEXT ? 1 : 0;
1240
    memcpy (vtdata.buffer.buffer, vcd->buffer.buffer, vtdata.buffer.totsize << 2);
1241
    vtdata.buffer.origin = 0;
1242
    if (text_mode) {
1243
        vt->vcd->screen.origin = old_origin;
1244
        set_scrmem (vt, 0);
1245
    } else
1246
        vt->vcd->screen.origin = SCREEN2_BASE;
1247
    vcd->driver = screen_driver;
1248
    gotoxy(vt->vcd, vt->vcd->curstate.x, vt->vcd->curstate.y);
1249
#ifdef DEBUG
1250
    vcd_validate (vt->vcd, "vcd_restorestate");
1251
#endif
1252
    set_origin(vt);
1253
    set_cursor(vt);
1254
    if (text_mode)
1255
        vcd_restorecursors (vt);
1256
    set_leds ();
1257
}
1258
 
1259
void vcd_setup_graphics (const struct vt *vt)
1260
{
1261
    clear_selection ();
1262
    vcd_removecursors (vt);
1263
    __set_origin (vtdata.screen.memstart);
1264
}
1265
 
1266
/*===============================================================================================*/
1267
 
1268
static int vcd_write_utf (struct con_struct *vcd, int c)
1269
{
1270
    /* Combine UTF-8 into Unicode */
1271
    /* Incomplete characters silently ignored */
1272
    if (c < 0x80) {
1273
        vcd->utf_count = 0;
1274
        return c;
1275
    }
1276
 
1277
    if (vcd->utf_count > 0 && (c & 0xc0) == 0x80) {
1278
        vcd->utf_char = (vcd->utf_char << 6) | (c & 0x3f);
1279
        if (--vcd->utf_count == 0)
1280
            return vcd->utf_char;
1281
        else
1282
            return -1;
1283
    } else {
1284
        unsigned int count, chr;
1285
        if ((c & 0xe0) == 0xc0) {
1286
            count = 1;
1287
            chr = (c & 0x1f);
1288
        } else if ((c & 0xf0) == 0xe0) {
1289
            count = 2;
1290
            chr = (c & 0x0f);
1291
        } else if ((c & 0xf8) == 0xf0) {
1292
            count = 3;
1293
            chr = (c & 0x07);
1294
        } else if ((c & 0xfc) == 0xf8) {
1295
            count = 4;
1296
            chr = (c & 0x03);
1297
        } else if ((c & 0xfe) == 0xfc) {
1298
            count = 5;
1299
            chr = (c & 0x01);
1300
        } else {
1301
            count = 0;
1302
            chr = 0;
1303
        }
1304
        vcd->utf_count = count;
1305
        vcd->utf_char = chr;
1306
        return -1;
1307
    }
1308
}
1309
 
1310
static int vcd_write_ctrl (const struct vt *vt, unsigned int c)
1311
{
1312
    struct con_struct *vcd = vt->vcd;
1313
    /*
1314
     *  Control characters can be used in the _middle_
1315
     *  of an escape sequence.
1316
     */
1317
    switch (c) {
1318
    case 0:
1319
        return 0;
1320
    case 7:
1321
        if (vcd->bell_duration)
1322
                vt_mksound (vcd->bell_pitch, 72, vcd->bell_duration);
1323
        return 0;
1324
    case 8:
1325
        if (vcd->need_wrap)
1326
            vcd->need_wrap = 0;
1327
        else if (vcd->curstate.x) {
1328
            vcd->curstate.x --;
1329
            if (vtdata.fgconsole == vt)
1330
                vcd->screen.pos -= vtdata.screen.bytespercharh;
1331
            vcd->buffer.pos -= 1;
1332
            vcd->need_wrap = 0;
1333
        }
1334
        return 0;
1335
    case 9:
1336
        if (vtdata.fgconsole == vt)
1337
            vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
1338
        vcd->buffer.pos -= vcd->curstate.x;
1339
        while (vcd->curstate.x < vtdata.numcolumns - 1) {
1340
            vcd->curstate.x++;
1341
            if (vcd->tab_stop[vcd->curstate.x >> 5] & (1 << (vcd->curstate.x & 31)))
1342
                break;
1343
        }
1344
        if (vtdata.fgconsole == vt)
1345
            vcd->screen.pos += vcd->curstate.x * vtdata.screen.bytespercharh;
1346
        vcd->buffer.pos += vcd->curstate.x;
1347
        return 0;
1348
    case 10:
1349
    case 11:
1350
    case 12:
1351
        if (vcd->curstate.y + 1 == vcd->bottom)
1352
            vcd->driver.scroll_up (vcd, vcd->top, vcd->bottom, 1);
1353
        else if (vcd->curstate.y < vtdata.numrows - 1) {
1354
            vcd->curstate.y ++;
1355
            if (vtdata.fgconsole == vt)
1356
                vcd->screen.pos += vtdata.screen.sizerow;
1357
            vcd->buffer.pos += vtdata.buffer.sizerow;
1358
        }
1359
        vcd->need_wrap = 0;
1360
        if (!is_kbd(lnm))
1361
            return 0;
1362
    case 13:
1363
        if (vtdata.fgconsole == vt)
1364
            vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
1365
        vcd->buffer.pos -= vcd->curstate.x;
1366
        vcd->curstate.x = vcd->need_wrap = 0;
1367
        return 0;
1368
    case 14:
1369
        vcd->curstate.flags |= FLG_CHRSET;
1370
        vcd->disp_ctrl = 1;
1371
        vcd->translate = set_translate(vcd->curstate.G1_charset);
1372
        return 1;
1373
    case 15:
1374
        vcd->curstate.flags &= ~FLG_CHRSET;
1375
        vcd->disp_ctrl = 0;
1376
        vcd->translate = set_translate(vcd->curstate.G0_charset);
1377
        return 1;
1378
    case 24:
1379
    case 26:
1380
        vcd->state = ESnormal;
1381
        return 0;
1382
    case 27:
1383
        vcd->state = ESesc;
1384
        return 0;
1385
    case 127:
1386
        /* ignored */
1387
        return 0;
1388
    case 128+27:
1389
        vcd->state = ESsquare;
1390
        return 0;
1391
    }
1392
 
1393
    switch(vcd->state) {
1394
    case ESesc:
1395
        vcd->state = ESnormal;
1396
        switch (c) {
1397
        case '[':
1398
            vcd->state = ESsquare;
1399
            break;
1400
        case ']':
1401
            vcd->state = ESnonstd;
1402
            break;
1403
        case '%':
1404
            vcd->state = ESpercent;
1405
            break;
1406
        case 'E':
1407
            if (vtdata.fgconsole == vt)
1408
                vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
1409
            vcd->buffer.pos -= vcd->curstate.x;
1410
            vcd->curstate.x = vcd->need_wrap = 0;
1411
        case 'D':
1412
            if (vcd->curstate.y + 1 == vcd->bottom)
1413
                vcd->driver.scroll_up (vcd, vcd->top, vcd->bottom, 1);
1414
            else if (vcd->curstate.y < vtdata.numrows - 1) {
1415
                vcd->curstate.y ++;
1416
                if (vtdata.fgconsole == vt)
1417
                    vcd->screen.pos += vtdata.screen.sizerow;
1418
                vcd->buffer.pos += vtdata.buffer.sizerow;
1419
            }
1420
            /* vcd->need_wrap = 0; why should we reset this when the x position is the same? */
1421
            break;
1422
        case 'M':
1423
            if (vcd->curstate.y == vcd->top)
1424
                vcd->driver.scroll_down (vcd, vcd->top, vcd->bottom, 1);
1425
            else if (vcd->curstate.y > 0) {
1426
                vcd->curstate.y --;
1427
                if (vtdata.fgconsole == vt)
1428
                    vcd->screen.pos -= vtdata.screen.sizerow;
1429
                vcd->buffer.pos -= vtdata.buffer.sizerow;
1430
            }
1431
            /* vcd->need_wrap = 0; why should we reset this when the x position is the same? */
1432
            break;
1433
        case 'H':
1434
            vcd->tab_stop[vcd->curstate.x >> 5] |= (1 << (vcd->curstate.x & 31));
1435
            break;
1436
        case 'Z':
1437
            respond_ID (*vt->tty);
1438
            break;
1439
        case '7':
1440
            vcd->savedstate = vcd->curstate;
1441
            break;
1442
        case '8':
1443
            vcd->curstate = vcd->savedstate;
1444
            gotoxy(vt->vcd, vt->vcd->curstate.x, vt->vcd->curstate.y);
1445
            update_attr (vt);
1446
            return 1;
1447
        case '(':
1448
            vcd->state = ESsetG0;
1449
            break;
1450
        case ')':
1451
            vcd->state = ESsetG1;
1452
            break;
1453
        case '#':
1454
            vcd->state = EShash;
1455
            break;
1456
        case 'c':
1457
            reset_terminal (vt, 0);
1458
            break;
1459
        case '>': /* Numeric keypad */
1460
            clr_kbd (kbdapplic);
1461
            break;
1462
        case '=': /* Appl. keypad */
1463
            set_kbd (kbdapplic);
1464
            break;
1465
        }
1466
        return 0;
1467
    case ESnonstd:
1468
        vcd->state = ESnormal;
1469
        switch (c) {
1470
        case 'P': /* palette escape sequence */
1471
            for (vcd->npar = 0; vcd->npar < NPAR; vcd->npar++)
1472
                vcd->par[vcd->npar] = 0;
1473
            vcd->npar = 0 ;
1474
            vcd->state = ESpalette;
1475
            return 0;
1476
        case 'R': /* reset palette */
1477
            con_reset_palette (vt);
1478
        default:
1479
            return 0;
1480
        }
1481
    case ESpalette:
1482
        if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) {
1483
            vcd->par[vcd->npar++] = (c > '9' ? (c & 0xDF) - 'A' + 10 : c - '0');
1484
            if (vcd->npar == 7) {
1485
#if TODO
1486
                int i = par[0]*3, j = 1;
1487
                palette[i] = 16*par[j++];
1488
                palette[i++] += par[j++];
1489
                palette[i] = 16*par[j++];
1490
                palette[i++] += par[j++];
1491
                palette[i] = 16*par[j++];
1492
                palette[i++] += par[j];
1493
#endif
1494
                con_set_palette (vt);
1495
                vcd->state = ESnormal;
1496
            }
1497
        } else
1498
            vcd->state = ESnormal;
1499
        return 0;
1500
    case ESsquare:
1501
        for (vcd->npar = 0; vcd->npar < NPAR; vcd->npar++)
1502
            vcd->par[vcd->npar] = 0;
1503
        vcd->npar = 0;
1504
        vcd->state = ESgetpars;
1505
        if (c == '[') { /* Function key */
1506
            vcd->state = ESfunckey;
1507
            return 0;
1508
        }
1509
 
1510
        vcd->ques = (c == '?');
1511
        if (vcd->ques)
1512
            return 0;
1513
    case ESgetpars:
1514
        if (c == ';' && vcd->npar < NPAR - 1) {
1515
            vcd->npar ++;
1516
            return 0;
1517
        } else
1518
        if (c >= '0' && c <= '9') {
1519
            vcd->par[vcd->npar] = vcd->par[vcd->npar] * 10 + c - '0';
1520
            return 0;
1521
        } else
1522
            vcd->state = ESgotpars;
1523
    case ESgotpars:
1524
        vcd->state=ESnormal;
1525
        switch (c) {
1526
        case 'h':
1527
            set_mode(vt, 1);
1528
            return 0;
1529
        case 'l':
1530
            set_mode(vt, 0);
1531
            return 0;
1532
        case 'n':
1533
            if (!vcd->ques) {
1534
                if (vcd->par[0] == 5)
1535
                    status_report (*vt->tty);
1536
                else
1537
                if (vcd->par[0] == 6)
1538
                    cursor_report (vt);
1539
            }
1540
            return 0;
1541
        }
1542
        if (vcd->ques) {
1543
                vcd->ques = 0;
1544
                return 0;
1545
        }
1546
        switch(c) {
1547
        case 'G':
1548
        case '`':
1549
            if (vcd->par[0])
1550
                vcd->par[0]--;
1551
            gotoxy (vcd, vcd->par[0], vcd->curstate.y);
1552
            return 0;
1553
        case 'A':
1554
            if (!vcd->par[0])
1555
                vcd->par[0]++;
1556
            gotoxy (vcd, vcd->curstate.x, vcd->curstate.y - vcd->par[0]);
1557
            return 0;
1558
        case 'B':
1559
        case 'e':
1560
            if (!vcd->par[0])
1561
                vcd->par[0]++;
1562
            gotoxy (vcd, vcd->curstate.x, vcd->curstate.y + vcd->par[0]);
1563
            return 0;
1564
        case 'C':
1565
        case 'a':
1566
            if (!vcd->par[0])
1567
                vcd->par[0]++;
1568
            gotoxy (vcd, vcd->curstate.x + vcd->par[0], vcd->curstate.y);
1569
            return 0;
1570
        case 'D':
1571
            if (!vcd->par[0])
1572
                vcd->par[0]++;
1573
            gotoxy (vcd, vcd->curstate.x - vcd->par[0], vcd->curstate.y);
1574
            return 0;
1575
        case 'E':
1576
            if (!vcd->par[0])
1577
                vcd->par[0]++;
1578
            gotoxy (vcd, 0, vcd->curstate.y + vcd->par[0]);
1579
            return 0;
1580
        case 'F':
1581
            if (!vcd->par[0])
1582
                vcd->par[0]++;
1583
            gotoxy (vcd, 0, vcd->curstate.y - vcd->par[0]);
1584
            return 0;
1585
        case 'd':
1586
            if (vcd->par[0])
1587
                vcd->par[0]--;
1588
            gotoxay (vcd, vcd->curstate.x, vcd->par[0]);
1589
            return 0;
1590
        case 'H':
1591
        case 'f':
1592
            if (vcd->par[0])
1593
                vcd->par[0]--;
1594
            if (vcd->par[1])
1595
                vcd->par[1]--;
1596
            gotoxay (vcd, vcd->par[1], vcd->par[0]);
1597
            return 0;
1598
        case 'J':
1599
            csi_J (vt, vcd->par[0]);
1600
            return 0;
1601
        case 'K':
1602
            csi_K (vt, vcd->par[0]);
1603
            return 0;
1604
        case 'L':
1605
            csi_L (vt, vcd->par[0]);
1606
            return 0;
1607
        case 'M':
1608
            csi_M (vt, vcd->par[0]);
1609
            return 0;
1610
        case 'P':
1611
            csi_P (vt, vcd->par[0]);
1612
            return 0;
1613
        case 'c':
1614
            if (!vcd->par[0])
1615
                respond_ID(*vt->tty);
1616
            return 0;
1617
        case 'g':
1618
            if (!vcd->par[0])
1619
                vcd->tab_stop[vcd->curstate.x >> 5] &= ~(1 << (vcd->curstate.x & 31));
1620
            else
1621
            if (vcd->par[0] == 3) {
1622
                vcd->tab_stop[0] =
1623
                vcd->tab_stop[1] =
1624
                vcd->tab_stop[2] =
1625
                vcd->tab_stop[3] =
1626
                vcd->tab_stop[4] = 0;
1627
            }
1628
            return 0;
1629
        case 'm':
1630
            return csi_m (vt);
1631
        case 'q': /* DECLL - but only 3 leds */
1632
            /* map 0,1,2,3 to 0,1,2,4 */
1633
            if (vcd->par[0] < 4)
1634
                  setledstate(vt->kbd, (vcd->par[0] < 3 ? vcd->par[0] : 4));
1635
            return 0;
1636
        case 'r':
1637
            if (!vcd->par[0])
1638
                vcd->par[0]++;
1639
            if (!vcd->par[1])
1640
                vcd->par[1] = vtdata.numrows;
1641
            if (vcd->par[0] < vcd->par[1] && vcd->par[1] <= vtdata.numrows) {
1642
                vcd->top = vcd->par[0] - 1;
1643
                vcd->bottom = vcd->par[1];
1644
                gotoxay (vcd, 0, 0);
1645
            }
1646
            return 0;
1647
        case 's':
1648
            vcd->savedstate = vcd->curstate;
1649
            return 0;
1650
        case 'u':
1651
            vcd->curstate = vcd->savedstate;
1652
            update_attr (vt);
1653
            return 1;
1654
        case 'X':
1655
            csi_X (vt, vcd->par[0]);
1656
            return 0;
1657
        case '@':
1658
            csi_at (vt, vcd->par[0]);
1659
            return 0;
1660
        case ']': /* setterm functions */
1661
            setterm_command (vt);
1662
            return 0;
1663
        }
1664
        return 0;
1665
    case ESpercent:
1666
        vcd->state = ESnormal;
1667
        switch (c) {
1668
        case '@': /* defined in ISO 2022 */
1669
            vcd->utf = 0;
1670
            return 0;
1671
        case 'G': /* prelim official escape code */
1672
        case '8': /* retained for compatibility */
1673
            vcd->utf = 1;
1674
            return 0;
1675
        }
1676
        return 0;
1677
    case ESfunckey:
1678
        vcd->state = ESnormal;
1679
        return 0;
1680
    case EShash:
1681
        vcd->state = ESnormal;
1682
        if (c == '8') {
1683
            /* DEC screen alignment test. kludge :-) */
1684
        }
1685
        return 0;
1686
    case ESsetG0:
1687
        vcd->state = ESnormal;
1688
        if (c == '0')
1689
            vcd->curstate.G0_charset = GRAF_MAP;
1690
        else
1691
        if (c == 'B')
1692
            vcd->curstate.G0_charset = LAT1_MAP;
1693
        else
1694
        if (c == 'U')
1695
            vcd->curstate.G0_charset = IBMPC_MAP;
1696
        else
1697
        if (c == 'K')
1698
            vcd->curstate.G0_charset = USER_MAP;
1699
        if ((vcd->curstate.flags & FLG_CHRSET) == 0) {
1700
            vcd->translate = set_translate(vcd->curstate.G0_charset);
1701
            return 1;
1702
        }
1703
        return 0;
1704
    case ESsetG1:
1705
        vcd->state = ESnormal;
1706
        if (c == '0')
1707
            vcd->curstate.G1_charset = GRAF_MAP;
1708
        else
1709
        if (c == 'B')
1710
            vcd->curstate.G1_charset = LAT1_MAP;
1711
        else
1712
        if (c == 'U')
1713
            vcd->curstate.G1_charset = IBMPC_MAP;
1714
        else
1715
        if (c == 'K')
1716
            vcd->curstate.G1_charset = USER_MAP;
1717
        if (vcd->curstate.flags & FLG_CHRSET) {
1718
            vcd->translate = set_translate(vcd->curstate.G1_charset);
1719
            return 1;
1720
        }
1721
        return 0;
1722
    default:
1723
        vcd->state = ESnormal;
1724
    }
1725
    return 0;
1726
}
1727
 
1728
static inline void vcd_write_char (struct con_struct *vcd, unsigned int c)
1729
{
1730
    if (c & ~console_charmask)
1731
        return;
1732
    vcd->driver.write_char (vcd, vcd->combined_state | (c & 255));
1733
}
1734
 
1735
int vcd_write (const struct vt *vt, int from_user, const unsigned char *buf, int count)
1736
{
1737
    int strt_count = count;
1738
    unsigned short *cached_trans;
1739
    unsigned int cached_ctrls;
1740
    register struct con_struct *vcd;
1741
 
1742
    if (from_user && get_fs () == KERNEL_DS)
1743
        from_user = 0;
1744
 
1745
    vcd = vt->vcd;
1746
 
1747
#ifdef DEBUG
1748
    vcd_validate (vcd, "vcd_write entry");
1749
#endif
1750
 
1751
    vcd_removecursors (vt);
1752
    if (vt == vtdata.select.vt)
1753
        clear_selection();
1754
 
1755
    disable_bh (CONSOLE_BH);
1756
recache:
1757
    cached_ctrls = vcd->disp_ctrl ? CTRL_ALWAYS : CTRL_ACTION;
1758
    cached_trans = vcd->translate + (vcd->toggle_meta ? 0x80 : 0);
1759
 
1760
    while (!(*vt->tty)->stopped && count) {
1761
        int tc, c;
1762
        enable_bh(CONSOLE_BH);
1763
        __asm__("teq    %3, #0
1764
        ldreqb  %0, [%1], #1
1765
        ldrnebt %0, [%1], #1" : "=r" (c), "=&r" (buf) : "1" (buf), "r" (from_user));
1766
        disable_bh(CONSOLE_BH);
1767
        count --;
1768
 
1769
        if (vcd->utf) {
1770
            if ((tc = vcd_write_utf (vcd, c)) < 0)
1771
                continue;
1772
            c = tc;
1773
        } else
1774
            tc = cached_trans[c];
1775
 
1776
        if (vcd->state == ESnormal && tc && (c != 127 || vcd->disp_ctrl) && (c != 128+27)) {
1777
            if (c >= 32 || (!vcd->utf && !(cached_ctrls & (1 << c)))) { /* ok */
1778
                tc = conv_uni_to_pc (tc);
1779
                if (tc == -4)
1780
                    /* If we got -4 (not found) then see if we have
1781
                       defined a replacement character (U+FFFD) */
1782
                    tc = conv_uni_to_pc (0xfffd);
1783
                else if (tc == -3)
1784
                    /* Bad hash table -- hope for the best */
1785
                    tc = c;
1786
 
1787
                vcd_write_char (vcd, tc);
1788
                continue;
1789
            }
1790
        }
1791
 
1792
        if (vcd_write_ctrl (vt, c))
1793
            goto recache;
1794
        else
1795
            continue;
1796
    }
1797
    if (vt->vtd->vc_mode != KD_GRAPHICS)
1798
        set_cursor (vt);
1799
    vcd_restorecursors (vt);
1800
    enable_bh(CONSOLE_BH);
1801
#ifdef DEBUG
1802
    vcd_validate (vcd, "vcd_write exit");
1803
#endif
1804
    return strt_count - count;
1805
}
1806
 
1807
int vcd_ioctl (const struct vt *vt, int cmd, unsigned long arg)
1808
{
1809
    int i;
1810
    switch (cmd) {
1811
    case VT_GETPALETTE: {
1812
        unsigned long pix, num, *ptr;
1813
        const unsigned long *entries;
1814
 
1815
        ptr = (unsigned long *)arg;
1816
 
1817
        if ((i = verify_area (VERIFY_READ, ptr, 12)) != 0)
1818
                return i;
1819
 
1820
        pix = get_user (ptr);
1821
        num = get_user (ptr + 1);
1822
        if (!num)
1823
                return 0;
1824
        if (pix > 255 || pix + num > 256)
1825
                return -EINVAL;
1826
 
1827
        ptr = (unsigned long *) get_user (ptr + 2);
1828
        if ((i = verify_area (VERIFY_WRITE, ptr, num * sizeof (unsigned long))) != 0)
1829
                return i;
1830
 
1831
        if (vt->vcd->screen.palette_entries)
1832
                entries = vt->vcd->screen.palette_entries + pix;
1833
        else
1834
                entries = default_palette_entries + pix;
1835
        memcpy_tofs(ptr, entries, num * sizeof (unsigned long));
1836
        return 0;
1837
        }
1838
    case VT_SETPALETTE: {
1839
        unsigned long pix, num, *ptr, *sval;
1840
 
1841
        ptr = (unsigned long *)arg;
1842
 
1843
        if ((i = verify_area (VERIFY_READ, ptr, 12)) != 0)
1844
                return i;
1845
 
1846
        pix = get_user (ptr);
1847
        num = get_user (ptr + 1);
1848
        if (!num)
1849
                return 0;
1850
        if (pix > 255 || pix + num > 256)
1851
                return -EINVAL;
1852
 
1853
        ptr = (unsigned long *) get_user (ptr + 2);
1854
        if ((i = verify_area (VERIFY_READ, ptr, num * sizeof (unsigned long))) != 0)
1855
                return i;
1856
 
1857
        if (!vt->vcd->screen.palette_entries) {
1858
                void *entries;
1859
                entries = kmalloc (sizeof (unsigned long) * 256, GFP_KERNEL);
1860
                if (!vt->vcd->screen.palette_entries) {
1861
                        if (!entries)
1862
                                return -ENOMEM;
1863
                        memcpy (entries, default_palette_entries, 256 * sizeof (unsigned long));
1864
                        vt->vcd->screen.palette_entries = entries;
1865
                }
1866
        }
1867
        sval = vt->vcd->screen.palette_entries + pix;
1868
        memcpy_fromfs (sval, ptr, num * sizeof (unsigned long));
1869
        palette_setpixel(pix);
1870
        for (i = num; i > 3; i -= 4) {
1871
            palette_write (*sval++);
1872
            palette_write (*sval++);
1873
            palette_write (*sval++);
1874
            palette_write (*sval++);
1875
        }
1876
        if (i & 2) {
1877
            palette_write (*sval++);
1878
            palette_write (*sval++);
1879
        }
1880
        if (i & 1)
1881
            palette_write (*sval++);
1882
        return 0;
1883
        }
1884
 
1885
    case PIO_FONT:
1886
        if (vt->vtd->vc_mode != KD_TEXT)
1887
            return -EINVAL;
1888
        return con_set_font((char *)arg);
1889
        /* con_set_font() defined in console.c */
1890
 
1891
    case GIO_FONT:
1892
        if (vt->vtd->vc_mode != KD_TEXT)
1893
            return -EINVAL;
1894
        return con_get_font((char *)arg);
1895
        /* con_get_font() defined in console.c */
1896
 
1897
    case PIO_SCRNMAP:
1898
        return con_set_trans_old ((char *)arg);
1899
 
1900
    case GIO_SCRNMAP:
1901
        return con_get_trans_old((char *)arg);
1902
 
1903
    case PIO_UNISCRNMAP:
1904
        return con_set_trans_new((short *)arg);
1905
 
1906
    case GIO_UNISCRNMAP:
1907
        return con_get_trans_new((short *)arg);
1908
 
1909
    case PIO_UNIMAPCLR: {
1910
        struct unimapinit ui;
1911
 
1912
        i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct unimapinit));
1913
        if (i)
1914
            return i;
1915
        memcpy_fromfs(&ui, (void *)arg, sizeof(struct unimapinit));
1916
        con_clear_unimap(&ui);
1917
        return 0;
1918
        }
1919
 
1920
    case PIO_UNIMAP: {
1921
        i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct unimapdesc));
1922
        if (i == 0) {
1923
            struct unimapdesc *ud;
1924
            u_short ct;
1925
            struct unipair *list;
1926
 
1927
            ud = (struct unimapdesc *) arg;
1928
            ct = get_fs_word(&ud->entry_ct);
1929
            list = (struct unipair *) get_fs_long(&ud->entries);
1930
 
1931
            i = verify_area(VERIFY_READ, (void *) list,
1932
                        ct*sizeof(struct unipair));
1933
            if (!i)
1934
                return con_set_unimap(ct, list);
1935
        }
1936
        return i;
1937
        }
1938
 
1939
    case GIO_UNIMAP: {
1940
        i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct unimapdesc));
1941
        if (i == 0) {
1942
            struct unimapdesc *ud;
1943
            u_short ct;
1944
            struct unipair *list;
1945
 
1946
            ud = (struct unimapdesc *) arg;
1947
            ct = get_fs_word(&ud->entry_ct);
1948
            list = (struct unipair *) get_fs_long(&ud->entries);
1949
            if (ct)
1950
                i = verify_area(VERIFY_WRITE, (void *) list,
1951
                        ct*sizeof(struct unipair));
1952
            if (!i)
1953
                return con_get_unimap(ct, &(ud->entry_ct), list);
1954
        }
1955
        return i;
1956
        }
1957
 
1958
    default:
1959
        return -ENOIOCTLCMD;
1960
    }
1961
}
1962
 
1963
void console_print(const char *b)
1964
{
1965
        static int printing = 0;
1966
        struct vt *vt = vtdata.fgconsole;
1967
        struct con_struct * const vcd = vt->vcd;
1968
        unsigned char c;
1969
 
1970
#ifdef DEBUG
1971
        vcd_validate (vcd, "console_print entry");
1972
#endif
1973
 
1974
        if (!printable || printing || vt->vtd->vc_mode == KD_GRAPHICS)
1975
                return;  /* console not yet initialized */
1976
        printing = 1;
1977
 
1978
        if (!vt_allocated(vtdata.fgconsole)) {
1979
                /* impossible */
1980
                printk ("console_print: tty %d not allocated ??\n", vtdata.fgconsole->num);
1981
                printing = 0;
1982
                return;
1983
        }
1984
 
1985
#ifdef CONFIG_SERIAL_ECHO
1986
        serial_echo_print (b);
1987
#endif
1988
        vcd_removecursors (vt);
1989
        while ((c = *b++) != 0)
1990
                screen_driver.put_char(vcd, vcd->combined_state | (c & 255));
1991
        set_cursor (vt);
1992
        vcd_restorecursors (vt);
1993
 
1994
        vt_pokeblankedconsole ();
1995
        printing = 0;
1996
#ifdef DEBUG
1997
        vcd_validate (vt->vcd, "console_print exit");
1998
#endif
1999
}
2000
 
2001
/*===============================================================================================*/
2002
 
2003
int vcd_init (struct vt *vt, int kmallocok, unsigned long *kmem)
2004
{
2005
        struct con_struct *vcd = vt->vcd;
2006
        memset (vcd, 0, sizeof (*vcd));
2007
 
2008
        vcd->screen.origin              = vtdata.screen.memstart;
2009
        vcd->screen.cursoron            = (kmem ? 1 : 0);
2010
        vcd->screen.palette_entries     = NULL;
2011
        vcd->driver                     = buffer_driver;
2012
        if (kmallocok) {
2013
                vcd->buffer.buffer      = vmalloc (vtdata.buffer.totsize * sizeof (unsigned long));
2014
                if (!vt->vcd->buffer.buffer)
2015
                        return -ENOMEM;
2016
                vcd->buffer.kmalloced   = 1;
2017
        } else {
2018
                vcd->buffer.buffer      = (unsigned long *) *kmem;
2019
                *kmem += vtdata.buffer.totsize * sizeof (unsigned long);
2020
        }
2021
 
2022
        vt->vtd->paste_wait             = NULL;
2023
        reset_terminal (vt, (kmem ? 1 : 0));
2024
        return 0;
2025
}
2026
 
2027
/*
2028
 * We allow this irq to be shared
2029
 */
2030
static struct irqaction vsyncirq = { vsync_irq, SA_SHIRQ, 0, "vsync", NULL, NULL };
2031
 
2032
unsigned long vcd_pre_init (unsigned long kmem, struct vt *vt)
2033
{
2034
        int colours, i;
2035
 
2036
        switch (bytes_per_char_h) {
2037
        default:
2038
        case 1:
2039
                default_palette_entries = palette_1;
2040
                vtdata.screen.bytespercharh = 1;
2041
                vtdata.screen.bitsperpix = 1;
2042
                color_table = color_1;
2043
                colours = 1;
2044
                break;
2045
        case 4:
2046
                default_palette_entries = palette_4;
2047
                vtdata.screen.bytespercharh = 4;
2048
                vtdata.screen.bitsperpix = 4;
2049
                color_table = color_4;
2050
                colours = 16;
2051
                for (i = 0; i < 256; i++)
2052
                        con_charconvtable[i] =
2053
                                (i & 128 ? 1 << 0  : 0) |
2054
                                (i & 64  ? 1 << 4  : 0) |
2055
                                (i & 32  ? 1 << 8  : 0) |
2056
                                (i & 16  ? 1 << 12 : 0) |
2057
                                (i & 8   ? 1 << 16 : 0) |
2058
                                (i & 4   ? 1 << 20 : 0) |
2059
                                (i & 2   ? 1 << 24 : 0) |
2060
                                (i & 1   ? 1 << 28 : 0);
2061
                break;
2062
        case 8:
2063
                default_palette_entries = palette_8;
2064
                vtdata.screen.bytespercharh = 8;
2065
                vtdata.screen.bitsperpix = 8;
2066
                color_table = color_8;
2067
                colours = 256;
2068
                for (i = 0; i < 16; i++)
2069
                        con_charconvtable[i] =
2070
                                (i & 8   ? 1 << 0  : 0) |
2071
                                (i & 4   ? 1 << 8  : 0) |
2072
                                (i & 2   ? 1 << 16 : 0) |
2073
                                (i & 1   ? 1 << 24 : 0);
2074
                break;
2075
        }
2076
        video_size_row          = vtdata.numcolumns * vtdata.screen.bytespercharh;
2077
        vtdata.screen.bytespercharv = bytes_per_char_v;
2078
        vtdata.screen.sizerow   = video_size_row * vtdata.screen.bytespercharv;
2079
        vtdata.screen.totsize   = vtdata.screen.sizerow * vtdata.numrows;
2080
 
2081
        vtdata.screen.memsize   = ((vtdata.screen.totsize - 1) | (PAGE_SIZE - 1)) + 1;
2082
        vtdata.screen.memend    = SCREEN1_END;
2083
        vtdata.screen.memstart  = vtdata.screen.memend - vtdata.screen.memsize;
2084
        vtdata.buffer.buffer    = (unsigned long *)kmem;
2085
        vtdata.buffer.sizerow   = vtdata.numcolumns;
2086
        vtdata.buffer.totsize   = vtdata.numcolumns * vtdata.numrows;
2087
        vtdata.buffer.lastorigin        = vtdata.buffer.totsize * 2;
2088
        kmem = (unsigned long)(vtdata.buffer.buffer + vtdata.buffer.totsize * 3);
2089
        memzero (vtdata.buffer.buffer, vtdata.buffer.totsize * 3 << 2);
2090
 
2091
        kmem = map_screen_mem (vtdata.screen.memstart, kmem, 1);
2092
 
2093
        palette_setpixel(0);
2094
        for (i = 0; i < MAX_PIX; i++)
2095
                palette_write(default_palette_entries[i]);
2096
 
2097
        vcd_init (vt, 0, &kmem);
2098
        vt->vcd->driver = screen_driver;
2099
 
2100
        gotoxy (vt->vcd, ORIG_X, ORIG_Y);
2101
        set_origin (vt);
2102
        csi_J (vt, 0);
2103
        printable = 1;
2104
 
2105
#ifdef CONFIG_SERIAL_ECHO
2106
        serial_echo_init (SERIAL_ECHO_PORT);
2107
#endif
2108
        printk ("Console: %s %s %dx%dx%d, %d virtual console%s (max %d)\n",
2109
                colours != 1 ? "colour" : "mono",
2110
                "A-series",
2111
                vtdata.numcolumns, vtdata.numrows, colours,
2112
                MIN_NR_CONSOLES,
2113
                (MIN_NR_CONSOLES == 1) ? "":"s",
2114
                MAX_NR_CONSOLES);
2115
 
2116
        register_console (console_print);
2117
 
2118
        if (setup_arm_irq(IRQ_VSYNCPULSE, &vsyncirq))
2119
                panic ("Unable to get VSYNC irq for console\n");
2120
 
2121
        return kmem;
2122
}
2123
 
2124
/*
2125
 * Report the current status of the vc. This is exported to modules (ARub)
2126
 */
2127
int con_get_info(int *mode, int *shift, int *col, int *row,
2128
                        struct tty_struct **tty)
2129
{
2130
        extern int shift_state;
2131
 
2132
        if (mode) *mode = vtdata.fgconsole->vtd->vc_mode;
2133
        if (shift) *shift = shift_state;
2134
        if (col) *col = vtdata.numcolumns;
2135
        if (row) *row = vtdata.numrows;
2136
        if (tty) *tty = *vtdata.fgconsole->tty;
2137
        return vtdata.fgconsole->num;
2138
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.