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] - Diff between revs 1765 and 1782

Only display areas with differences | Details | Blame | View Log

Rev 1765 Rev 1782
/*
/*
 * linux/arch/arm/drivers/char/console.c
 * linux/arch/arm/drivers/char/console.c
 *
 *
 * Modifications (C) 1995, 1996 Russell King
 * Modifications (C) 1995, 1996 Russell King
 */
 */
 
 
/*
/*
 * This module exports the console io functions:
 * This module exports the console io functions:
 *
 *
 *  'int           vcd_init (struct vt *vt, int kmallocok, unsigned long *kmem)'
 *  'int           vcd_init (struct vt *vt, int kmallocok, unsigned long *kmem)'
 *  'unsigned long vcd_pre_init (unsigned long kmem, struct vt *vt)'
 *  'unsigned long vcd_pre_init (unsigned long kmem, struct vt *vt)'
 *  'void          vcd_disallocate (struct vt *vt)'
 *  'void          vcd_disallocate (struct vt *vt)'
 *  'int           vcd_resize (unsigned long lines, unsigned long cols)'
 *  'int           vcd_resize (unsigned long lines, unsigned long cols)'
 *  'void          vcd_blankscreen (int nopowersave)'
 *  'void          vcd_blankscreen (int nopowersave)'
 *  'void          vcd_unblankscreen (void)'
 *  'void          vcd_unblankscreen (void)'
 *  'void          vcd_savestate (const struct vt *vt, int blanked)'
 *  'void          vcd_savestate (const struct vt *vt, int blanked)'
 *  'void          vcd_restorestate (const struct vt *vt)'
 *  'void          vcd_restorestate (const struct vt *vt)'
 *  'void          vcd_setup_graphics (const struct vt *vt)'
 *  'void          vcd_setup_graphics (const struct vt *vt)'
 *  'int           vcd_write (const struct vt *vt, int from_user, const unsigned char *buf, int count)'
 *  'int           vcd_write (const struct vt *vt, int from_user, const unsigned char *buf, int count)'
 *  'int           vcd_ioctl (const struct vt *vt, int cmd, unsigned long arg)'
 *  'int           vcd_ioctl (const struct vt *vt, int cmd, unsigned long arg)'
 *
 *
 *
 *
 *      'unsigned long con_init(unsigned long)'
 *      'unsigned long con_init(unsigned long)'
 * S    'int con_open(struct tty_struct *tty,struct file *filp)'
 * S    'int con_open(struct tty_struct *tty,struct file *filp)'
 * S    'void con_write(struct tty_struct *tty)'
 * S    'void con_write(struct tty_struct *tty)'
 * S    'void console_print(const char *b)'
 * S    'void console_print(const char *b)'
 *
 *
 *      'void unblank_screen(void)'
 *      'void unblank_screen(void)'
 *      'void scrollback(int lines)'                    *
 *      'void scrollback(int lines)'                    *
 *      'void scrollfront(int lines)'                   *
 *      'void scrollfront(int lines)'                   *
 *      'int do_screendump(int arg)'
 *      'int do_screendump(int arg)'
 *
 *
 *      'int con_get_font(char *)'
 *      'int con_get_font(char *)'
 *      'int con_set_font(char *)'
 *      'int con_set_font(char *)'
 *      'int con_get_trans(char *)'
 *      'int con_get_trans(char *)'
 *      'int con_set_trans(char *)'
 *      'int con_set_trans(char *)'
 *
 *
 *      'int mouse_reporting(void)'
 *      'int mouse_reporting(void)'
 */
 */
 
 
#define BLANK 0x0020
#define BLANK 0x0020
 
 
/* A bitmap for codes <32. A bit of 1 indicates that the code
/* A bitmap for codes <32. A bit of 1 indicates that the code
 * corresponding to that bit number invokes a special action
 * corresponding to that bit number invokes a special action
 * (such as cursor movement) and should not be displayed as a
 * (such as cursor movement) and should not be displayed as a
 * glyph unless the disp_ctrl mode is explicitly enabled.
 * glyph unless the disp_ctrl mode is explicitly enabled.
 */
 */
#define CTRL_ACTION 0x0d00ff81
#define CTRL_ACTION 0x0d00ff81
#define CTRL_ALWAYS 0x0800f501  /* Cannot be overriden by disp_ctrl */
#define CTRL_ALWAYS 0x0800f501  /* Cannot be overriden by disp_ctrl */
 
 
/*
/*
 * Here is the default bell parameters: 750HZ, 1/8th of a second
 * Here is the default bell parameters: 750HZ, 1/8th of a second
 */
 */
#define DEFAULT_BELL_PITCH      750
#define DEFAULT_BELL_PITCH      750
#define DEFAULT_BELL_DURATION   (HZ/8)
#define DEFAULT_BELL_DURATION   (HZ/8)
 
 
/*
/*
 *  NOTE!!! We sometimes disable and enable interrupts for a short while
 *  NOTE!!! We sometimes disable and enable interrupts for a short while
 * (to put a word in video IO), but this will work even for keyboard
 * (to put a word in video IO), but this will work even for keyboard
 * interrupts. We know interrupts aren't enabled when getting a keyboard
 * interrupts. We know interrupts aren't enabled when getting a keyboard
 * interrupt, as we use trap-gates. Hopefully all is well.
 * interrupt, as we use trap-gates. Hopefully all is well.
 */
 */
 
 
#include <linux/config.h>
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/tty_flip.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/kd.h>
#include <linux/kd.h>
#include <linux/major.h>
#include <linux/major.h>
#include <linux/malloc.h>
#include <linux/malloc.h>
#include <linux/mm.h>
#include <linux/mm.h>
 
 
#include <asm/io.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/segment.h>
#include <asm/irq.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/hardware.h>
 
 
#define DEBUG
#define DEBUG
 
 
#include "kbd_kern.h"
#include "kbd_kern.h"
#include "consolemap.h"
#include "consolemap.h"
#include "vt_kern.h"
#include "vt_kern.h"
#include "selection.h"
#include "selection.h"
 
 
#define set_kbd(x) set_vc_kbd_mode (vt->kbd, x)
#define set_kbd(x) set_vc_kbd_mode (vt->kbd, x)
#define clr_kbd(x) clr_vc_kbd_mode (vt->kbd, x)
#define clr_kbd(x) clr_vc_kbd_mode (vt->kbd, x)
#define is_kbd(x)  vc_kbd_mode (vt->kbd, x)
#define is_kbd(x)  vc_kbd_mode (vt->kbd, x)
 
 
#define decarm          VC_REPEAT
#define decarm          VC_REPEAT
#define decckm          VC_CKMODE
#define decckm          VC_CKMODE
#define kbdapplic       VC_APPLIC
#define kbdapplic       VC_APPLIC
#define lnm             VC_CRLF
#define lnm             VC_CRLF
 
 
/*
/*
 * this is what the terminal answers to a ESC-Z or csi0c query.
 * this is what the terminal answers to a ESC-Z or csi0c query.
 */
 */
#define VT100ID "\033[?1;2c"
#define VT100ID "\033[?1;2c"
#define VT102ID "\033[?6c"
#define VT102ID "\033[?6c"
 
 
extern int setup_arm_irq(int, struct irqaction *);
extern int setup_arm_irq(int, struct irqaction *);
 
 
/*
/*
 * routines to load custom translation table, EGA/VGA font and
 * routines to load custom translation table, EGA/VGA font and
 * VGA colour palette from console.c
 * VGA colour palette from console.c
 */
 */
extern int con_set_trans_old(unsigned char * table);
extern int con_set_trans_old(unsigned char * table);
extern int con_get_trans_old(unsigned char * table);
extern int con_get_trans_old(unsigned char * table);
extern int con_set_trans_new(unsigned short * table);
extern int con_set_trans_new(unsigned short * table);
extern int con_get_trans_new(unsigned short * table);
extern int con_get_trans_new(unsigned short * table);
extern void con_clear_unimap(struct unimapinit *ui);
extern void con_clear_unimap(struct unimapinit *ui);
extern int con_set_unimap(ushort ct, struct unipair *list);
extern int con_set_unimap(ushort ct, struct unipair *list);
extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list);
extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list);
extern void con_set_default_unimap(void);
extern void con_set_default_unimap(void);
extern int con_set_font(char * fontmap);
extern int con_set_font(char * fontmap);
extern int con_get_font(char * fontmap);
extern int con_get_font(char * fontmap);
 
 
 
 
/* ARM Extensions */
/* ARM Extensions */
#if defined(HAS_VIDC)
#if defined(HAS_VIDC)
 
 
extern void memc_write (int reg, int val);
extern void memc_write (int reg, int val);
extern void vidc_write (int reg, int val);
extern void vidc_write (int reg, int val);
static int __r;
static int __r;
#define palette_setpixel(p) __r = p
#define palette_setpixel(p) __r = p
#define palette_write(v)                        \
#define palette_write(v)                        \
{                                               \
{                                               \
  int rr = __r++, red, green, blue, vv = (v);   \
  int rr = __r++, red, green, blue, vv = (v);   \
  red   = (vv >> 4)  & 0x00f;                   \
  red   = (vv >> 4)  & 0x00f;                   \
  green = (vv >> 8)  & 0x0f0;                   \
  green = (vv >> 8)  & 0x0f0;                   \
  blue  = (vv >> 12) & 0xf00;                   \
  blue  = (vv >> 12) & 0xf00;                   \
  outl((rr<<26)|red|green|blue, IO_VIDC_BASE);  \
  outl((rr<<26)|red|green|blue, IO_VIDC_BASE);  \
}
}
 
 
#define MAX_PIX 16
#define MAX_PIX 16
 
 
#elif defined(HAS_VIDC20)
#elif defined(HAS_VIDC20)
#define palette_setpixel(p)     outl(0x10000000|((p) & 255), IO_VIDC_BASE)
#define palette_setpixel(p)     outl(0x10000000|((p) & 255), IO_VIDC_BASE)
#define palette_write(v)        outl(0x00000000|((v) & 0x00ffffff), IO_VIDC_BASE)
#define palette_write(v)        outl(0x00000000|((v) & 0x00ffffff), IO_VIDC_BASE)
#define MAX_PIX 256
#define MAX_PIX 256
#endif
#endif
 
 
/*
/*
 * from ll_wr_char.S
 * from ll_wr_char.S
 */
 */
int bytes_per_char_h, bytes_per_char_v, video_size_row;
int bytes_per_char_h, bytes_per_char_v, video_size_row;
extern void ll_write_char(unsigned long ps, unsigned long chinfo);
extern void ll_write_char(unsigned long ps, unsigned long chinfo);
extern unsigned long con_charconvtable[256];
extern unsigned long con_charconvtable[256];
extern unsigned long map_screen_mem (unsigned long vid_base, unsigned long kmem, int remap);
extern unsigned long map_screen_mem (unsigned long vid_base, unsigned long kmem, int remap);
#include <linux/ctype.h>
#include <linux/ctype.h>
 
 
extern struct console_driver screen_driver, buffer_driver;
extern struct console_driver screen_driver, buffer_driver;
 
 
#ifndef MIN
#ifndef MIN
#define MIN(a,b)        ((a) < (b) ? (a) : (b))
#define MIN(a,b)        ((a) < (b) ? (a) : (b))
#endif
#endif
 
 
static void gotoxy (struct con_struct *vcd, int new_x, int new_y);
static void gotoxy (struct con_struct *vcd, int new_x, int new_y);
static inline void set_cursor (const struct vt * const vt);
static inline void set_cursor (const struct vt * const vt);
extern void reset_vc(const struct vt * const vt);
extern void reset_vc(const struct vt * const vt);
extern void register_console(void (*proc)(const char *));
extern void register_console(void (*proc)(const char *));
extern void compute_shiftstate(void);
extern void compute_shiftstate(void);
extern void con_reset_palette (const struct vt * const vt);
extern void con_reset_palette (const struct vt * const vt);
extern void con_set_palette (const struct vt * const vt);
extern void con_set_palette (const struct vt * const vt);
 
 
static int printable;                           /* Is console ready for printing? */
static int printable;                           /* Is console ready for printing? */
 
 
#define console_charmask 0xff
#define console_charmask 0xff
#ifndef console_charmask
#ifndef console_charmask
static unsigned short console_charmask = 0x0ff;
static unsigned short console_charmask = 0x0ff;
#endif
#endif
 
 
#include "font.h"
#include "font.h"
 
 
static const unsigned long palette_1[MAX_PIX] = {
static const unsigned long palette_1[MAX_PIX] = {
        0x00000000,             /* Black   */
        0x00000000,             /* Black   */
        0x00ffffff,             /* White   */
        0x00ffffff,             /* White   */
        0x00000000              /* Black   */
        0x00000000              /* Black   */
};
};
 
 
static const unsigned long palette_4[MAX_PIX] = {
static const unsigned long palette_4[MAX_PIX] = {
        0x00000000,             /* Black   */
        0x00000000,             /* Black   */
        0x000000cc,             /* Red     */
        0x000000cc,             /* Red     */
        0x0000cc00,             /* Green   */
        0x0000cc00,             /* Green   */
        0x0000cccc,             /* Yellow  */
        0x0000cccc,             /* Yellow  */
        0x00cc0000,             /* Blue    */
        0x00cc0000,             /* Blue    */
        0x00cc00cc,             /* Magenta */
        0x00cc00cc,             /* Magenta */
        0x00cccc00,             /* Cyan    */
        0x00cccc00,             /* Cyan    */
        0x00cccccc,             /* White   */
        0x00cccccc,             /* White   */
        0x00000000,
        0x00000000,
        0x000000ff,
        0x000000ff,
        0x0000ff00,
        0x0000ff00,
        0x0000ffff,
        0x0000ffff,
        0x00ff0000,
        0x00ff0000,
        0x00ff00ff,
        0x00ff00ff,
        0x00ffff00,
        0x00ffff00,
        0x00ffffff
        0x00ffffff
};
};
 
 
#if defined(HAS_VIDC)
#if defined(HAS_VIDC)
static const unsigned long palette_8[MAX_PIX] = {
static const unsigned long palette_8[MAX_PIX] = {
        0x00000000,
        0x00000000,
        0x00111111,
        0x00111111,
        0x00222222,
        0x00222222,
        0x00333333,
        0x00333333,
        0x00440000,
        0x00440000,
        0x00551111,
        0x00551111,
        0x00662222,
        0x00662222,
        0x00773333,
        0x00773333,
        0x00000044,
        0x00000044,
        0x00111155,
        0x00111155,
        0x00222266,
        0x00222266,
        0x00333377,
        0x00333377,
        0x00440044,
        0x00440044,
        0x00551155,
        0x00551155,
        0x00662266,
        0x00662266,
        0x00773377
        0x00773377
};
};
#elif defined(HAS_VIDC20)
#elif defined(HAS_VIDC20)
#define palette_8 palette_4
#define palette_8 palette_4
#endif
#endif
 
 
static const unsigned long *default_palette_entries = palette_4;
static const unsigned long *default_palette_entries = palette_4;
 
 
static const unsigned char color_1[] = {0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 };
static const unsigned char color_1[] = {0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 };
static const unsigned char color_4[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 };
static const unsigned char color_4[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 };
#if defined(HAS_VIDC)
#if defined(HAS_VIDC)
static const unsigned char color_8[] = {0x00, 0x18, 0x60, 0x78, 0x84, 0x9C, 0xE4, 0xFC,
static const unsigned char color_8[] = {0x00, 0x18, 0x60, 0x78, 0x84, 0x9C, 0xE4, 0xFC,
                                        0x00, 0x1B, 0x63, 0x7B, 0x87, 0x9F, 0xE7, 0xFF};
                                        0x00, 0x1B, 0x63, 0x7B, 0x87, 0x9F, 0xE7, 0xFF};
#elif defined(HAS_VIDC20)
#elif defined(HAS_VIDC20)
static const unsigned char color_8[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 };
static const unsigned char color_8[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 };
#endif
#endif
static const unsigned char *color_table = color_4;
static const unsigned char *color_table = color_4;
 
 
/*===================================================================================*/
/*===================================================================================*/
 
 
#ifdef CONFIG_SERIAL_ECHO
#ifdef CONFIG_SERIAL_ECHO
#include "serialecho.c"
#include "serialecho.c"
#endif
#endif
 
 
/*
/*
 * functions to handle /dev/fb
 * functions to handle /dev/fb
 */
 */
int con_fb_read(char *buf, unsigned long pos, int count)
int con_fb_read(char *buf, unsigned long pos, int count)
{
{
        return -EIO;
        return -EIO;
}
}
 
 
int con_fb_write(const char *buf, unsigned long pos, int count)
int con_fb_write(const char *buf, unsigned long pos, int count)
{
{
        return -EIO;
        return -EIO;
}
}
 
 
int con_fb_mmap(unsigned long vma_start, unsigned long vma_offset,
int con_fb_mmap(unsigned long vma_start, unsigned long vma_offset,
                        unsigned long vma_end, pgprot_t prot)
                        unsigned long vma_end, pgprot_t prot)
{
{
        if (vma_offset > vtdata.screen.memsize ||
        if (vma_offset > vtdata.screen.memsize ||
            vma_end - vma_start + vma_offset > vtdata.screen.memsize)
            vma_end - vma_start + vma_offset > vtdata.screen.memsize)
                return -EINVAL;
                return -EINVAL;
        return remap_page_range(vma_start, SCREEN2_BASE + vma_offset,
        return remap_page_range(vma_start, SCREEN2_BASE + vma_offset,
                                vma_end - vma_start, prot);
                                vma_end - vma_start, prot);
}
}
 
 
#ifdef DEBUG
#ifdef DEBUG
static int vcd_validate (struct con_struct *vcd, const char *msg)
static int vcd_validate (struct con_struct *vcd, const char *msg)
{
{
    unsigned long old_scrorigin, old_scrpos, old_buforigin, old_bufpos, w = 0;
    unsigned long old_scrorigin, old_scrpos, old_buforigin, old_bufpos, w = 0;
 
 
    old_scrorigin = vcd->screen.origin;
    old_scrorigin = vcd->screen.origin;
    old_scrpos = vcd->screen.pos;
    old_scrpos = vcd->screen.pos;
    old_buforigin = vtdata.buffer.origin;
    old_buforigin = vtdata.buffer.origin;
    old_bufpos = vcd->buffer.pos;
    old_bufpos = vcd->buffer.pos;
    if (vcd->screen.origin < SCREEN1_BASE || vcd->screen.origin > SCREEN1_END) {
    if (vcd->screen.origin < SCREEN1_BASE || vcd->screen.origin > SCREEN1_END) {
        vcd->screen.origin = SCREEN2_BASE;
        vcd->screen.origin = SCREEN2_BASE;
        w = 1;
        w = 1;
    }
    }
    if (vcd->screen.pos < SCREEN1_BASE || vcd->screen.pos > SCREEN2_END) {
    if (vcd->screen.pos < SCREEN1_BASE || vcd->screen.pos > SCREEN2_END) {
        vcd->screen.pos = SCREEN2_BASE;
        vcd->screen.pos = SCREEN2_BASE;
        w = 1;
        w = 1;
    }
    }
 
 
    if (w)
    if (w)
        printk ("*** CONSOLE ERROR: %s: (%p): origin = %08lX pos = %08lX ***\n",
        printk ("*** CONSOLE ERROR: %s: (%p): origin = %08lX pos = %08lX ***\n",
                                msg, vcd, old_scrorigin, old_scrpos);
                                msg, vcd, old_scrorigin, old_scrpos);
    return w;
    return w;
}
}
#endif
#endif
 
 
void no_scroll(char *str, int *ints)
void no_scroll(char *str, int *ints)
{
{
}
}
 
 
static unsigned long __origin;          /* Offset of currently displayed screen */
static unsigned long __origin;          /* Offset of currently displayed screen */
 
 
static void __set_origin(unsigned long offset)
static void __set_origin(unsigned long offset)
{
{
        unsigned long flags;
        unsigned long flags;
 
 
        clear_selection ();
        clear_selection ();
 
 
        offset = offset - vtdata.screen.memstart;
        offset = offset - vtdata.screen.memstart;
        if (offset >= vtdata.screen.memsize)
        if (offset >= vtdata.screen.memsize)
                offset -= vtdata.screen.memsize;
                offset -= vtdata.screen.memsize;
 
 
        save_flags_cli (flags);
        save_flags_cli (flags);
        __origin = offset;
        __origin = offset;
        video_set_dma(0, vtdata.screen.memsize, offset);
        video_set_dma(0, vtdata.screen.memsize, offset);
        restore_flags(flags);
        restore_flags(flags);
}
}
 
 
void scrollback(int lines)
void scrollback(int lines)
{
{
}
}
 
 
void scrollfront(int lines)
void scrollfront(int lines)
{
{
}
}
 
 
void scroll_set_origin (unsigned long offset)
void scroll_set_origin (unsigned long offset)
{
{
        __set_origin(offset);
        __set_origin(offset);
}
}
 
 
static void set_origin (const struct vt * const vt)
static void set_origin (const struct vt * const vt)
{
{
        if (vtdata.fgconsole != vt || vt->vtd->vc_mode == KD_GRAPHICS)
        if (vtdata.fgconsole != vt || vt->vtd->vc_mode == KD_GRAPHICS)
                return;
                return;
        __set_origin(vt->vcd->screen.origin);
        __set_origin(vt->vcd->screen.origin);
}
}
 
 
/* -------------------------------------------------------------------------------
/* -------------------------------------------------------------------------------
 * Cursor
 * Cursor
 * ------------------------------------------------------------------------------- */
 * ------------------------------------------------------------------------------- */
 
 
static char cursor_on = 0;
static char cursor_on = 0;
static unsigned long cp;
static unsigned long cp;
 
 
static void put_cursor(char on_off,unsigned long newcp)
static void put_cursor(char on_off,unsigned long newcp)
{
{
        static char con;
        static char con;
        unsigned long cp_p = cp;
        unsigned long cp_p = cp;
        int c = vtdata.screen.bytespercharh == 8 ? color_table[15] : 0x11 * color_table[15];
        int c = vtdata.screen.bytespercharh == 8 ? color_table[15] : 0x11 * color_table[15];
        int i;
        int i;
 
 
        if (vtdata.fgconsole->vtd->vc_mode == KD_GRAPHICS)
        if (vtdata.fgconsole->vtd->vc_mode == KD_GRAPHICS)
                return;
                return;
 
 
        cp = newcp;
        cp = newcp;
 
 
        if (con != on_off) {
        if (con != on_off) {
                if (cp_p != -1)
                if (cp_p != -1)
                        for (i = 0; i < vtdata.screen.bytespercharh; i++)
                        for (i = 0; i < vtdata.screen.bytespercharh; i++)
                                ((unsigned char*)cp_p)[i]^=c;
                                ((unsigned char*)cp_p)[i]^=c;
                con = on_off;
                con = on_off;
        }
        }
}
}
 
 
static void vsync_irq(int irq, void *dev_id, struct pt_regs *regs)
static void vsync_irq(int irq, void *dev_id, struct pt_regs *regs)
{
{
        static char cursor_flash = 16;
        static char cursor_flash = 16;
 
 
        if (!--cursor_flash) {
        if (!--cursor_flash) {
                cursor_flash = 16;
                cursor_flash = 16;
                cursor_on = cursor_on ? 0 : 1;
                cursor_on = cursor_on ? 0 : 1;
                if (vtdata.fgconsole->vcd->screen.cursoron > 0)
                if (vtdata.fgconsole->vcd->screen.cursoron > 0)
                        put_cursor(cursor_on,cp);
                        put_cursor(cursor_on,cp);
        }
        }
}
}
 
 
static void hide_cursor(void)
static void hide_cursor(void)
{
{
        put_cursor (0, -1);
        put_cursor (0, -1);
}
}
 
 
static void set_cursor (const struct vt * const vt)
static void set_cursor (const struct vt * const vt)
{
{
        unsigned long flags;
        unsigned long flags;
 
 
        if (vt != vtdata.fgconsole || vt->vtd->vc_mode == KD_GRAPHICS)
        if (vt != vtdata.fgconsole || vt->vtd->vc_mode == KD_GRAPHICS)
                return;
                return;
 
 
        save_flags_cli (flags);
        save_flags_cli (flags);
        if (vt->vcd->deccm) {
        if (vt->vcd->deccm) {
#ifdef DEBUG
#ifdef DEBUG
                vcd_validate (vt->vcd, "set_cursor");
                vcd_validate (vt->vcd, "set_cursor");
#endif
#endif
                cp = vt->vcd->screen.pos + vtdata.numcolumns *
                cp = vt->vcd->screen.pos + vtdata.numcolumns *
                        vtdata.screen.bytespercharh * (vtdata.screen.bytespercharv - 1);
                        vtdata.screen.bytespercharh * (vtdata.screen.bytespercharv - 1);
        } else
        } else
                hide_cursor();
                hide_cursor();
        restore_flags(flags);
        restore_flags(flags);
}
}
 
 
static void vcd_removecursors (const struct vt *vt)
static void vcd_removecursors (const struct vt *vt)
{
{
        unsigned long flags;
        unsigned long flags;
 
 
        save_flags_cli (flags);
        save_flags_cli (flags);
 
 
        if (--vt->vcd->screen.cursoron == 0 && vtdata.fgconsole == vt)
        if (--vt->vcd->screen.cursoron == 0 && vtdata.fgconsole == vt)
                put_cursor (0, cp);
                put_cursor (0, cp);
 
 
        restore_flags (flags);
        restore_flags (flags);
}
}
 
 
static void vcd_restorecursors(const struct vt *vt)
static void vcd_restorecursors(const struct vt *vt)
{
{
        unsigned long flags;
        unsigned long flags;
 
 
        save_flags_cli (flags);
        save_flags_cli (flags);
 
 
        if (++vt->vcd->screen.cursoron == 1 && cursor_on && vtdata.fgconsole == vt)
        if (++vt->vcd->screen.cursoron == 1 && cursor_on && vtdata.fgconsole == vt)
                put_cursor (1, cp);
                put_cursor (1, cp);
 
 
        restore_flags (flags);
        restore_flags (flags);
}
}
 
 
/* -----------------------------------------------------------------------------------------
/* -----------------------------------------------------------------------------------------
 * VC stuff
 * VC stuff
 * ----------------------------------------------------------------------------------------- */
 * ----------------------------------------------------------------------------------------- */
/*
/*
 * gotoxy() must verify all boundaries, because the arguments
 * gotoxy() must verify all boundaries, because the arguments
 * might also be negative. If a given position is out of
 * might also be negative. If a given position is out of
 * bounds, the cursor is placed at the nearest margin.
 * bounds, the cursor is placed at the nearest margin.
 */
 */
static void gotoxy (struct con_struct *vcd, int new_x, int new_y)
static void gotoxy (struct con_struct *vcd, int new_x, int new_y)
{
{
    int min_y, max_y;
    int min_y, max_y;
 
 
    if (new_x < 0)
    if (new_x < 0)
        vcd->curstate.x = 0;
        vcd->curstate.x = 0;
    else
    else
    if (new_x >= vtdata.numcolumns)
    if (new_x >= vtdata.numcolumns)
        vcd->curstate.x = vtdata.numcolumns - 1;
        vcd->curstate.x = vtdata.numcolumns - 1;
    else
    else
        vcd->curstate.x = new_x;
        vcd->curstate.x = new_x;
 
 
    if (vcd->decom) {
    if (vcd->decom) {
        new_y += vcd->top;
        new_y += vcd->top;
        min_y = vcd->top;
        min_y = vcd->top;
        max_y = vcd->bottom;
        max_y = vcd->bottom;
    } else {
    } else {
        min_y = 0;
        min_y = 0;
        max_y = vtdata.numrows;
        max_y = vtdata.numrows;
    }
    }
 
 
    if (new_y < min_y)
    if (new_y < min_y)
        vcd->curstate.y = min_y;
        vcd->curstate.y = min_y;
    else if (new_y >= max_y)
    else if (new_y >= max_y)
        vcd->curstate.y = max_y - 1;
        vcd->curstate.y = max_y - 1;
    else
    else
        vcd->curstate.y = new_y;
        vcd->curstate.y = new_y;
 
 
    vcd->driver.gotoxy (vcd);
    vcd->driver.gotoxy (vcd);
    vcd->need_wrap = 0;
    vcd->need_wrap = 0;
#ifdef DEBUG
#ifdef DEBUG
    vcd_validate (vcd, "gotoxy");
    vcd_validate (vcd, "gotoxy");
#endif
#endif
}
}
 
 
/* for absolute user moves, when decom is set */
/* for absolute user moves, when decom is set */
static void gotoxay (struct con_struct *vcd, int new_x, int new_y)
static void gotoxay (struct con_struct *vcd, int new_x, int new_y)
{
{
    gotoxy(vcd, new_x, vcd->decom ? (vcd->top+new_y) : new_y);
    gotoxy(vcd, new_x, vcd->decom ? (vcd->top+new_y) : new_y);
}
}
 
 
static void update_attr (const struct vt * const vt)
static void update_attr (const struct vt * const vt)
{
{
    unsigned int backcol, forecol;
    unsigned int backcol, forecol;
 
 
    backcol = color_table[vt->vcd->curstate.backcol];
    backcol = color_table[vt->vcd->curstate.backcol];
    if (vt->vcd->curstate.flags & FLG_BOLD)
    if (vt->vcd->curstate.flags & FLG_BOLD)
        forecol = color_table[vt->vcd->curstate.forecol + 8];
        forecol = color_table[vt->vcd->curstate.forecol + 8];
    else
    else
        forecol = color_table[vt->vcd->curstate.forecol];
        forecol = color_table[vt->vcd->curstate.forecol];
    vt->vcd->combined_state = (vt->vcd->curstate.flags << 24) |
    vt->vcd->combined_state = (vt->vcd->curstate.flags << 24) |
                              (backcol << 16) |
                              (backcol << 16) |
                              (forecol << 8);
                              (forecol << 8);
    switch (vtdata.screen.bitsperpix) {
    switch (vtdata.screen.bitsperpix) {
    case 1:
    case 1:
        vt->vcd->cached_backcolwrd = 0;
        vt->vcd->cached_backcolwrd = 0;
        break;
        break;
    default:
    default:
    case 4:
    case 4:
        vt->vcd->cached_backcolwrd = 0x11111111 * backcol;
        vt->vcd->cached_backcolwrd = 0x11111111 * backcol;
        break;
        break;
    case 8:
    case 8:
        vt->vcd->cached_backcolwrd = 0x01010101 * backcol;
        vt->vcd->cached_backcolwrd = 0x01010101 * backcol;
        break;
        break;
    }
    }
}
}
 
 
static void default_attr (const struct vt * const vt)
static void default_attr (const struct vt * const vt)
{
{
    vt->vcd->curstate.flags &= ~(FLG_INVERSE|FLG_FLASH|FLG_UNDERLINE|FLG_ITALIC|FLG_BOLD);
    vt->vcd->curstate.flags &= ~(FLG_INVERSE|FLG_FLASH|FLG_UNDERLINE|FLG_ITALIC|FLG_BOLD);
    vt->vcd->curstate.forecol = vt->vcd->def_forecol;
    vt->vcd->curstate.forecol = vt->vcd->def_forecol;
    vt->vcd->curstate.backcol = vt->vcd->def_backcol;
    vt->vcd->curstate.backcol = vt->vcd->def_backcol;
}
}
 
 
static int csi_m (const struct vt * const vt)
static int csi_m (const struct vt * const vt)
{
{
    struct con_struct *vcd = vt->vcd;
    struct con_struct *vcd = vt->vcd;
    int i, ret = 0;
    int i, ret = 0;
 
 
    for (i = 0; i <= vcd->npar; i++) {
    for (i = 0; i <= vcd->npar; i++) {
        switch (vcd->par[i]) {
        switch (vcd->par[i]) {
        case 0:
        case 0:
            default_attr (vt);
            default_attr (vt);
            break;
            break;
        case 1:
        case 1:
            vcd->curstate.flags |= FLG_BOLD;
            vcd->curstate.flags |= FLG_BOLD;
            break;      /* Bold */
            break;      /* Bold */
        case 2:
        case 2:
            vcd->curstate.flags &= ~FLG_BOLD;
            vcd->curstate.flags &= ~FLG_BOLD;
            break;      /* Feint */
            break;      /* Feint */
        case 3:
        case 3:
            vcd->curstate.flags |= FLG_ITALIC;
            vcd->curstate.flags |= FLG_ITALIC;
            break;      /* Italic */
            break;      /* Italic */
        case 4:
        case 4:
            vcd->curstate.flags |= FLG_UNDERLINE;
            vcd->curstate.flags |= FLG_UNDERLINE;
            break;      /* Underline */
            break;      /* Underline */
        case 5:
        case 5:
        case 6:
        case 6:
            vcd->curstate.flags |= FLG_FLASH;
            vcd->curstate.flags |= FLG_FLASH;
            break;      /* Flash */
            break;      /* Flash */
        case 7:
        case 7:
            vcd->curstate.flags |= FLG_INVERSE;
            vcd->curstate.flags |= FLG_INVERSE;
            break;      /* Inverse chars */
            break;      /* Inverse chars */
 
 
        case 10:
        case 10:
            /* ANSI X3.64-1979 (SCO-ish?)
            /* ANSI X3.64-1979 (SCO-ish?)
             * Select primary font, don't display
             * Select primary font, don't display
             * control chars if defined, don't set
             * control chars if defined, don't set
             * bit 8 on output.
             * bit 8 on output.
             */
             */
            vcd->translate = set_translate(vcd->curstate.flags & FLG_CHRSET
            vcd->translate = set_translate(vcd->curstate.flags & FLG_CHRSET
                                ? vcd->curstate.G1_charset
                                ? vcd->curstate.G1_charset
                                : vcd->curstate.G0_charset);
                                : vcd->curstate.G0_charset);
            vcd->disp_ctrl = 0;
            vcd->disp_ctrl = 0;
            vcd->toggle_meta = 0;
            vcd->toggle_meta = 0;
            ret = 1;
            ret = 1;
            break;
            break;
        case 11:
        case 11:
            /* ANSI X3.64-1979 (SCO-ish?)
            /* ANSI X3.64-1979 (SCO-ish?)
             * Select first alternate font, let's
             * Select first alternate font, let's
             * chars < 32 be displayed as ROM chars.
             * chars < 32 be displayed as ROM chars.
             */
             */
            vcd->translate = set_translate(IBMPC_MAP);
            vcd->translate = set_translate(IBMPC_MAP);
            vcd->disp_ctrl = 1;
            vcd->disp_ctrl = 1;
            vcd->toggle_meta = 0;
            vcd->toggle_meta = 0;
            ret = 1;
            ret = 1;
            break;
            break;
        case 12:
        case 12:
            /* ANSI X3.64-1979 (SCO-ish?)
            /* ANSI X3.64-1979 (SCO-ish?)
             * Select second alternate font, toggle
             * Select second alternate font, toggle
             * high bit before displaying as ROM char.
             * high bit before displaying as ROM char.
             */
             */
            vcd->translate = set_translate(IBMPC_MAP);
            vcd->translate = set_translate(IBMPC_MAP);
            vcd->disp_ctrl = 1;
            vcd->disp_ctrl = 1;
            vcd->toggle_meta = 1;
            vcd->toggle_meta = 1;
            ret = 1;
            ret = 1;
            break;
            break;
        case 21:
        case 21:
        case 22:
        case 22:
            vcd->curstate.flags &= ~FLG_BOLD;
            vcd->curstate.flags &= ~FLG_BOLD;
            break;
            break;
        case 24:
        case 24:
            vcd->curstate.flags &= ~FLG_UNDERLINE;
            vcd->curstate.flags &= ~FLG_UNDERLINE;
            break;
            break;
        case 25:
        case 25:
            vcd->curstate.flags &= ~FLG_FLASH;
            vcd->curstate.flags &= ~FLG_FLASH;
            break;
            break;
        case 27:
        case 27:
            vcd->curstate.flags &= ~FLG_INVERSE;
            vcd->curstate.flags &= ~FLG_INVERSE;
            break;
            break;
        case 30:
        case 30:
        case 31:
        case 31:
        case 32:
        case 32:
        case 33:
        case 33:
        case 34:
        case 34:
        case 35:
        case 35:
        case 36:
        case 36:
        case 37:
        case 37:
            vcd->curstate.forecol = vcd->par[i]-30;
            vcd->curstate.forecol = vcd->par[i]-30;
            break;                                              /* Foreground colour */
            break;                                              /* Foreground colour */
        case 38:
        case 38:
            vcd->curstate.forecol = vcd->def_forecol;
            vcd->curstate.forecol = vcd->def_forecol;
            vcd->curstate.flags &= ~FLG_UNDERLINE;
            vcd->curstate.flags &= ~FLG_UNDERLINE;
            break;
            break;
        case 39:
        case 39:
            vcd->curstate.forecol = vcd->def_forecol;
            vcd->curstate.forecol = vcd->def_forecol;
            vcd->curstate.flags &= ~FLG_UNDERLINE;
            vcd->curstate.flags &= ~FLG_UNDERLINE;
            break;                                              /* Default foreground colour */
            break;                                              /* Default foreground colour */
        case 40:
        case 40:
        case 41:
        case 41:
        case 42:
        case 42:
        case 43:
        case 43:
        case 44:
        case 44:
        case 45:
        case 45:
        case 46:
        case 46:
        case 47:
        case 47:
            vcd->curstate.backcol = vcd->par[i]-40;
            vcd->curstate.backcol = vcd->par[i]-40;
            break;                                              /* Background colour */
            break;                                              /* Background colour */
        case 49:
        case 49:
            vcd->curstate.backcol = vcd->def_backcol;
            vcd->curstate.backcol = vcd->def_backcol;
            break;                                              /* Default background colour */
            break;                                              /* Default background colour */
        }
        }
    }
    }
    update_attr (vt);
    update_attr (vt);
    return ret;
    return ret;
}
}
 
 
static void respond_string (char *p, struct tty_struct *tty)
static void respond_string (char *p, struct tty_struct *tty)
{
{
    while (*p)
    while (*p)
        tty_insert_flip_char (tty, *p++, 0);
        tty_insert_flip_char (tty, *p++, 0);
    tty_schedule_flip (tty);
    tty_schedule_flip (tty);
}
}
 
 
static void cursor_report (const struct vt *vt)
static void cursor_report (const struct vt *vt)
{
{
    char buf[40];
    char buf[40];
 
 
    sprintf (buf, "\033[%d;%dR", vt->vcd->curstate.y + (vt->vcd->decom ? vt->vcd->top + 1 : 1),
    sprintf (buf, "\033[%d;%dR", vt->vcd->curstate.y + (vt->vcd->decom ? vt->vcd->top + 1 : 1),
                                     vt->vcd->curstate.x + 1);
                                     vt->vcd->curstate.x + 1);
    respond_string (buf, *vt->tty);
    respond_string (buf, *vt->tty);
}
}
 
 
static void status_report (struct tty_struct *tty)
static void status_report (struct tty_struct *tty)
{
{
    respond_string ("\033[0n", tty);
    respond_string ("\033[0n", tty);
}
}
 
 
static void respond_ID (struct tty_struct *tty)
static void respond_ID (struct tty_struct *tty)
{
{
    respond_string(VT102ID, tty);
    respond_string(VT102ID, tty);
}
}
 
 
void mouse_report (struct tty_struct *tty, int butt, int mrx, int mry)
void mouse_report (struct tty_struct *tty, int butt, int mrx, int mry)
{
{
    char buf[8];
    char buf[8];
 
 
    sprintf (buf,"\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
    sprintf (buf,"\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
        (char)('!'+mry));
        (char)('!'+mry));
    respond_string(buf, tty);
    respond_string(buf, tty);
}
}
 
 
/* invoked by ioctl(TIOCLINUX) */
/* invoked by ioctl(TIOCLINUX) */
int mouse_reporting (void)
int mouse_reporting (void)
{
{
    return vtdata.fgconsole->vcd->report_mouse;
    return vtdata.fgconsole->vcd->report_mouse;
}
}
 
 
static inline unsigned long screenpos (const struct vt * const vt, int offset)
static inline unsigned long screenpos (const struct vt * const vt, int offset)
{
{
    int hx, hy;
    int hx, hy;
 
 
    hx = offset % vtdata.numcolumns;
    hx = offset % vtdata.numcolumns;
    hy = offset / vtdata.numcolumns;
    hy = offset / vtdata.numcolumns;
    return vt->vcd->screen.origin + hy * vtdata.screen.sizerow + hx * vtdata.screen.bytespercharh;
    return vt->vcd->screen.origin + hy * vtdata.screen.sizerow + hx * vtdata.screen.bytespercharh;
}
}
 
 
void invert_screen (const struct vt * const vt, unsigned int offset, unsigned int count)
void invert_screen (const struct vt * const vt, unsigned int offset, unsigned int count)
{
{
    struct con_struct *vcd = vt->vcd;
    struct con_struct *vcd = vt->vcd;
    unsigned long *buffer = vcd->driver.buffer_pos(vcd, offset);
    unsigned long *buffer = vcd->driver.buffer_pos(vcd, offset);
    unsigned long p, pp;
    unsigned long p, pp;
    int i;
    int i;
 
 
    for (i = 0; i <= count; i++)
    for (i = 0; i <= count; i++)
        buffer[i] ^= FLG_INVERSE << 24;
        buffer[i] ^= FLG_INVERSE << 24;
 
 
    if (vt == vtdata.fgconsole) {
    if (vt == vtdata.fgconsole) {
        int hx, hy, hex, hey;
        int hx, hy, hex, hey;
 
 
        hx = offset % vtdata.numcolumns;
        hx = offset % vtdata.numcolumns;
        hy = offset / vtdata.numcolumns;
        hy = offset / vtdata.numcolumns;
        hex = (offset + count) % vtdata.numcolumns;
        hex = (offset + count) % vtdata.numcolumns;
        hey = (offset + count) / vtdata.numcolumns;
        hey = (offset + count) / vtdata.numcolumns;
 
 
        p = vcd->screen.origin + hy * vtdata.screen.sizerow;
        p = vcd->screen.origin + hy * vtdata.screen.sizerow;
        pp = p + hx * vtdata.screen.bytespercharh;
        pp = p + hx * vtdata.screen.bytespercharh;
        for (;hy <= hey; hy ++) {
        for (;hy <= hey; hy ++) {
            for (; hx < ((hy == hey) ? hex + 1 : vtdata.numcolumns); hx ++) {
            for (; hx < ((hy == hey) ? hex + 1 : vtdata.numcolumns); hx ++) {
                ll_write_char (pp, *buffer++);
                ll_write_char (pp, *buffer++);
                pp += vtdata.screen.bytespercharh;
                pp += vtdata.screen.bytespercharh;
            }
            }
            hx = 0;
            hx = 0;
            pp = p += vtdata.screen.sizerow;
            pp = p += vtdata.screen.sizerow;
        }
        }
    }
    }
}
}
 
 
void complement_pos (const struct vt * const vt, unsigned int offset)
void complement_pos (const struct vt * const vt, unsigned int offset)
{
{
    static unsigned long old = 0;
    static unsigned long old = 0;
    static unsigned long p = 0;
    static unsigned long p = 0;
    unsigned long complement;
    unsigned long complement;
 
 
    switch (vtdata.screen.bitsperpix) {
    switch (vtdata.screen.bitsperpix) {
    case 4:
    case 4:
        complement = 0x00070700;
        complement = 0x00070700;
        break;
        break;
    case 8:
    case 8:
#ifndef HAS_VIDC20
#ifndef HAS_VIDC20
        complement = 0x00fcfc00;
        complement = 0x00fcfc00;
#else
#else
        complement = 0x00070700;
        complement = 0x00070700;
#endif
#endif
        break;
        break;
    default:
    default:
        complement = 0;
        complement = 0;
    }
    }
 
 
    if (p)
    if (p)
        ll_write_char (p, old);
        ll_write_char (p, old);
    if ((int)offset == -1)
    if ((int)offset == -1)
        p = 0;
        p = 0;
    else {
    else {
        old = *vt->vcd->driver.buffer_pos(vt->vcd, offset);
        old = *vt->vcd->driver.buffer_pos(vt->vcd, offset);
        p = screenpos (vt, offset);
        p = screenpos (vt, offset);
        ll_write_char (p, old ^ complement);
        ll_write_char (p, old ^ complement);
    }
    }
}
}
 
 
unsigned long screen_word (const struct vt * const vt, unsigned int offset)
unsigned long screen_word (const struct vt * const vt, unsigned int offset)
{
{
    return *vt->vcd->driver.buffer_pos (vt->vcd, offset);
    return *vt->vcd->driver.buffer_pos (vt->vcd, offset);
}
}
 
 
int scrw2glyph (unsigned long scr_word)
int scrw2glyph (unsigned long scr_word)
{
{
    return scr_word & 255;
    return scr_word & 255;
}
}
 
 
unsigned long *screen_pos (const struct vt * const vt, unsigned int offset)
unsigned long *screen_pos (const struct vt * const vt, unsigned int offset)
{
{
    return vt->vcd->driver.buffer_pos (vt->vcd, offset);
    return vt->vcd->driver.buffer_pos (vt->vcd, offset);
}
}
 
 
void getconsxy (const struct vt * const vt, char *p)
void getconsxy (const struct vt * const vt, char *p)
{
{
    p[0] = vt->vcd->curstate.x;
    p[0] = vt->vcd->curstate.x;
    p[1] = vt->vcd->curstate.y;
    p[1] = vt->vcd->curstate.y;
}
}
 
 
void putconsxy (const struct vt * const vt, char *p)
void putconsxy (const struct vt * const vt, char *p)
{
{
    gotoxy (vt->vcd, p[0], p[1]);
    gotoxy (vt->vcd, p[0], p[1]);
    set_cursor (vt);
    set_cursor (vt);
}
}
 
 
static void csi_J (const struct vt * const vt, int vpar);
static void csi_J (const struct vt * const vt, int vpar);
 
 
static void set_mode (const struct vt * const vt, int on_off)
static void set_mode (const struct vt * const vt, int on_off)
{
{
    struct con_struct *vcd = vt->vcd;
    struct con_struct *vcd = vt->vcd;
    int i;
    int i;
 
 
    for (i = 0; i <= vcd->npar; i++)
    for (i = 0; i <= vcd->npar; i++)
        if (vcd->ques)
        if (vcd->ques)
            switch(vcd->par[i]) {       /* DEC private modes set/reset */
            switch(vcd->par[i]) {       /* DEC private modes set/reset */
            case 1:                     /* Cursor keys send ^[Ox/^[[x */
            case 1:                     /* Cursor keys send ^[Ox/^[[x */
                if (on_off)
                if (on_off)
                    set_kbd(decckm);
                    set_kbd(decckm);
                else
                else
                    clr_kbd(decckm);
                    clr_kbd(decckm);
                break;
                break;
            case 3:             /* 80/132 mode switch unimplemented */
            case 3:             /* 80/132 mode switch unimplemented */
                vcd->deccolm = on_off;
                vcd->deccolm = on_off;
                csi_J (vt, 2);
                csi_J (vt, 2);
                gotoxy (vcd, 0, 0);
                gotoxy (vcd, 0, 0);
                break;
                break;
            case 5:             /* Inverted screen on/off */
            case 5:             /* Inverted screen on/off */
                if (vcd->decscnm != on_off) {
                if (vcd->decscnm != on_off) {
                    vcd->decscnm = on_off;
                    vcd->decscnm = on_off;
                    invert_screen (vt, 0, vtdata.buffer.totsize);
                    invert_screen (vt, 0, vtdata.buffer.totsize);
                    update_attr (vt);
                    update_attr (vt);
                }
                }
                break;
                break;
            case 6:             /* Origin relative/absolute */
            case 6:             /* Origin relative/absolute */
                vcd->decom = on_off;
                vcd->decom = on_off;
                gotoxay (vcd, 0, 0);
                gotoxay (vcd, 0, 0);
                break;
                break;
            case 7:             /* Autowrap on/off */
            case 7:             /* Autowrap on/off */
                vcd->decawm = on_off;
                vcd->decawm = on_off;
                break;
                break;
            case 8:             /* Autorepeat on/off */
            case 8:             /* Autorepeat on/off */
                if (on_off)
                if (on_off)
                    set_kbd(decarm);
                    set_kbd(decarm);
                else
                else
                    clr_kbd(decarm);
                    clr_kbd(decarm);
                break;
                break;
            case 9:
            case 9:
                vcd->report_mouse = on_off ? 1 : 0;
                vcd->report_mouse = on_off ? 1 : 0;
                break;
                break;
            case 25:            /* Cursor on/off */
            case 25:            /* Cursor on/off */
                vcd->deccm = on_off;
                vcd->deccm = on_off;
                set_cursor (vt);
                set_cursor (vt);
                break;
                break;
            case 1000:
            case 1000:
                vcd->report_mouse = on_off ? 2 : 0;
                vcd->report_mouse = on_off ? 2 : 0;
                break;
                break;
            }
            }
        else
        else
            switch(vcd->par[i]) {       /* ANSI modes set/reset */
            switch(vcd->par[i]) {       /* ANSI modes set/reset */
            case 3:                     /* Monitor (display ctrls) */
            case 3:                     /* Monitor (display ctrls) */
                vcd->disp_ctrl = on_off;
                vcd->disp_ctrl = on_off;
                break;
                break;
            case 4:                     /* Insert mode on/off */
            case 4:                     /* Insert mode on/off */
                vcd->decim = on_off;
                vcd->decim = on_off;
                break;
                break;
            case 20:                    /* Lf, Enter = CrLf/Lf */
            case 20:                    /* Lf, Enter = CrLf/Lf */
                if (on_off)
                if (on_off)
                    set_kbd(lnm);
                    set_kbd(lnm);
                else
                else
                    clr_kbd(lnm);
                    clr_kbd(lnm);
                break;
                break;
            }
            }
}
}
 
 
static void setterm_command (const struct vt * const vt)
static void setterm_command (const struct vt * const vt)
{
{
        struct con_struct *vcd = vt->vcd;
        struct con_struct *vcd = vt->vcd;
        switch (vt->vcd->par[0]) {
        switch (vt->vcd->par[0]) {
                case 1: /* Set colour for underline mode (implemented as an underline) */
                case 1: /* Set colour for underline mode (implemented as an underline) */
                case 2: /* set colour for half intensity mode (unimplemented) */
                case 2: /* set colour for half intensity mode (unimplemented) */
                        break;
                        break;
                case 8:
                case 8:
                        vcd->def_forecol = vcd->curstate.forecol;
                        vcd->def_forecol = vcd->curstate.forecol;
                        vcd->def_backcol = vcd->curstate.backcol;
                        vcd->def_backcol = vcd->curstate.backcol;
                        break;
                        break;
                case 9:
                case 9:
                        vtdata.screen.blankinterval =
                        vtdata.screen.blankinterval =
                                ((vcd->par[1] < 60) ? vcd->par[1] : 60) * 60 * HZ;
                                ((vcd->par[1] < 60) ? vcd->par[1] : 60) * 60 * HZ;
                        vt_pokeblankedconsole ();
                        vt_pokeblankedconsole ();
                        break;
                        break;
                case 10: /* set bell frequency in Hz */
                case 10: /* set bell frequency in Hz */
                        if (vcd->npar >= 1)
                        if (vcd->npar >= 1)
                                vcd->bell_pitch = vcd->par[1];
                                vcd->bell_pitch = vcd->par[1];
                        else
                        else
                                vcd->bell_pitch = DEFAULT_BELL_PITCH;
                                vcd->bell_pitch = DEFAULT_BELL_PITCH;
                        break;
                        break;
                case 11: /* set bell duration in msec */
                case 11: /* set bell duration in msec */
                        if (vcd->npar >= 1)
                        if (vcd->npar >= 1)
                                vcd->bell_duration = (vcd->par[1] < 2000) ?
                                vcd->bell_duration = (vcd->par[1] < 2000) ?
                                        vcd->par[1]*HZ/1000 : 0;
                                        vcd->par[1]*HZ/1000 : 0;
                        else
                        else
                                vcd->bell_duration = DEFAULT_BELL_DURATION;
                                vcd->bell_duration = DEFAULT_BELL_DURATION;
                        break;
                        break;
                case 12: { /* bring specified console to the front */
                case 12: { /* bring specified console to the front */
                        int arg = vcd->par[1];
                        int arg = vcd->par[1];
                        if (arg >= 1 && vt_allocated(vt_con_data + (arg - 1) ))
                        if (arg >= 1 && vt_allocated(vt_con_data + (arg - 1) ))
                                vt_updatescreen(vt_con_data + (arg - 1));
                                vt_updatescreen(vt_con_data + (arg - 1));
                        break;
                        break;
                        }
                        }
                case 13: /* unblank the screen */
                case 13: /* unblank the screen */
                        vt_do_unblankscreen ();
                        vt_do_unblankscreen ();
                        break;
                        break;
                case 14: /* set vesa powerdown interval */
                case 14: /* set vesa powerdown interval */
#if todo
#if todo
                        vesa_off_interval = ((vcd->par[1] < 60) ? vcd->par[1] : 60) * 60 * HZ;
                        vesa_off_interval = ((vcd->par[1] < 60) ? vcd->par[1] : 60) * 60 * HZ;
#endif
#endif
                        break;
                        break;
        }
        }
}
}
 
 
static void csi_J (const struct vt * const vt, int vpar)
static void csi_J (const struct vt * const vt, int vpar)
{
{
    unsigned char endx, endy;
    unsigned char endx, endy;
    unsigned char startx, starty;
    unsigned char startx, starty;
 
 
    switch (vpar) {
    switch (vpar) {
    case 0: /* erase from cursor to bottom of screen (including char at (x, y) */
    case 0: /* erase from cursor to bottom of screen (including char at (x, y) */
        startx = vt->vcd->curstate.x;
        startx = vt->vcd->curstate.x;
        starty = vt->vcd->curstate.y;
        starty = vt->vcd->curstate.y;
        endx   = vtdata.numcolumns - 1;
        endx   = vtdata.numcolumns - 1;
        endy   = vtdata.numrows - 1;
        endy   = vtdata.numrows - 1;
        break;
        break;
    case 1: /* erase from top of screen to cursor (including char at (x, y) */
    case 1: /* erase from top of screen to cursor (including char at (x, y) */
        startx = 0;
        startx = 0;
        starty = 0;
        starty = 0;
        endx   = vt->vcd->curstate.x;
        endx   = vt->vcd->curstate.x;
        endy   = vt->vcd->curstate.y;
        endy   = vt->vcd->curstate.y;
        break;
        break;
    case 2: /* erase entire screen */
    case 2: /* erase entire screen */
        startx = 0;
        startx = 0;
        starty = 0;
        starty = 0;
        endx   = vtdata.numcolumns - 1;
        endx   = vtdata.numcolumns - 1;
        endy   = vtdata.numrows - 1;
        endy   = vtdata.numrows - 1;
#if TODO
#if TODO
        origin = video_mem_base;
        origin = video_mem_base;
        set_origin (currcons);
        set_origin (currcons);
        gotoxy (currcons, x, y);
        gotoxy (currcons, x, y);
#endif
#endif
        break;
        break;
    default:
    default:
        return;
        return;
    }
    }
    vt->vcd->driver.erase (vt->vcd, startx, starty, endx, endy);
    vt->vcd->driver.erase (vt->vcd, startx, starty, endx, endy);
    /*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
    /*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
}
}
 
 
static void csi_K (const struct vt * const vt, int vpar)
static void csi_K (const struct vt * const vt, int vpar)
{
{
    unsigned char endx;
    unsigned char endx;
    unsigned char startx;
    unsigned char startx;
 
 
    switch(vpar) {
    switch(vpar) {
    case 0: /* erase from cursor to end of line */
    case 0: /* erase from cursor to end of line */
        startx = vt->vcd->curstate.x;
        startx = vt->vcd->curstate.x;
        endx   = vtdata.numcolumns - 1;
        endx   = vtdata.numcolumns - 1;
        break;
        break;
    case 1: /* erase from beginning of line to cursor */
    case 1: /* erase from beginning of line to cursor */
        startx = 0;
        startx = 0;
        endx   = vt->vcd->curstate.x;
        endx   = vt->vcd->curstate.x;
        break;
        break;
    case 2: /* erase entire line */
    case 2: /* erase entire line */
        startx = 0;
        startx = 0;
        endx   = vtdata.numcolumns - 1;
        endx   = vtdata.numcolumns - 1;
        break;
        break;
    default:
    default:
        return;
        return;
    }
    }
    vt->vcd->driver.erase(vt->vcd, startx, vt->vcd->curstate.y, endx, vt->vcd->curstate.y);
    vt->vcd->driver.erase(vt->vcd, startx, vt->vcd->curstate.y, endx, vt->vcd->curstate.y);
    /*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
    /*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
}
}
 
 
static void csi_X (const struct vt * const vt, int vpar) /* erase the following vpar positions */
static void csi_X (const struct vt * const vt, int vpar) /* erase the following vpar positions */
{                                                        /* not vt100? */
{                                                        /* not vt100? */
    unsigned char countx, county;
    unsigned char countx, county;
    unsigned char startx, starty;
    unsigned char startx, starty;
 
 
    if (!vpar)
    if (!vpar)
        vpar++;
        vpar++;
 
 
    startx = vt->vcd->curstate.x;
    startx = vt->vcd->curstate.x;
    starty = vt->vcd->curstate.y;
    starty = vt->vcd->curstate.y;
    countx = 0;
    countx = 0;
    county = 0;
    county = 0;
#if TODO
#if TODO
    vt->vcd->driver.erase(vt->vcd,startx,starty,countx,county);
    vt->vcd->driver.erase(vt->vcd,startx,starty,countx,county);
#endif
#endif
    /*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
    /*vt->vcd->need_wrap = 0; why? We don't move the cursor... */
}
}
 
 
static void csi_at (const struct vt * const vt, int nr)
static void csi_at (const struct vt * const vt, int nr)
{
{
    if (nr > vtdata.numcolumns - vt->vcd->curstate.x)
    if (nr > vtdata.numcolumns - vt->vcd->curstate.x)
        nr = vtdata.numcolumns - vt->vcd->curstate.x;
        nr = vtdata.numcolumns - vt->vcd->curstate.x;
    else if (!nr)
    else if (!nr)
        nr = 1;
        nr = 1;
    vt->vcd->driver.insert_char(vt->vcd, nr);
    vt->vcd->driver.insert_char(vt->vcd, nr);
}
}
 
 
static void csi_L (const struct vt * const vt, int nr)
static void csi_L (const struct vt * const vt, int nr)
{
{
    if (nr > vtdata.numrows - vt->vcd->curstate.y)
    if (nr > vtdata.numrows - vt->vcd->curstate.y)
        nr = vtdata.numrows - vt->vcd->curstate.y;
        nr = vtdata.numrows - vt->vcd->curstate.y;
    else if (!nr)
    else if (!nr)
        nr = 1;
        nr = 1;
    vt->vcd->driver.scroll_down (vt->vcd, vt->vcd->curstate.y, vt->vcd->bottom, nr);
    vt->vcd->driver.scroll_down (vt->vcd, vt->vcd->curstate.y, vt->vcd->bottom, nr);
/*  vt->vcd->need_wrap = 0; why? We haven't moved the cursor. */
/*  vt->vcd->need_wrap = 0; why? We haven't moved the cursor. */
}
}
 
 
static void csi_P (const struct vt * const vt, int nr)
static void csi_P (const struct vt * const vt, int nr)
{
{
    if (nr > vtdata.numcolumns)
    if (nr > vtdata.numcolumns)
        nr = vtdata.numcolumns;
        nr = vtdata.numcolumns;
    else if (!nr)
    else if (!nr)
        nr = 1;
        nr = 1;
    vt->vcd->driver.delete_char(vt->vcd, nr);
    vt->vcd->driver.delete_char(vt->vcd, nr);
}
}
 
 
static void csi_M (const struct vt * const vt, int nr)
static void csi_M (const struct vt * const vt, int nr)
{
{
    if (nr > vtdata.numrows)
    if (nr > vtdata.numrows)
        nr = vtdata.numrows;
        nr = vtdata.numrows;
    else if (!nr)
    else if (!nr)
        nr = 1;
        nr = 1;
    vt->vcd->driver.scroll_up (vt->vcd, vt->vcd->curstate.y, vt->vcd->bottom, nr);
    vt->vcd->driver.scroll_up (vt->vcd, vt->vcd->curstate.y, vt->vcd->bottom, nr);
/*  vt->vcd->need_wrap = 0; why? we haven't moved the cursor. */
/*  vt->vcd->need_wrap = 0; why? we haven't moved the cursor. */
}
}
 
 
enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
        EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
        EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
        ESpalette };
        ESpalette };
 
 
static void reset_terminal (const struct vt * const vt, int initialising)
static void reset_terminal (const struct vt * const vt, int initialising)
{
{
    struct con_struct *vcd;
    struct con_struct *vcd;
 
 
    vcd = vt->vcd;
    vcd = vt->vcd;
 
 
    vcd->top                    = 0;
    vcd->top                    = 0;
    vcd->bottom                 = vtdata.numrows;
    vcd->bottom                 = vtdata.numrows;
    vcd->state                  = ESnormal;
    vcd->state                  = ESnormal;
    vcd->ques                   = 0;
    vcd->ques                   = 0;
    vcd->translate              = set_translate (LAT1_MAP);
    vcd->translate              = set_translate (LAT1_MAP);
    vcd->curstate.G0_charset    = LAT1_MAP;
    vcd->curstate.G0_charset    = LAT1_MAP;
    vcd->curstate.G1_charset    = GRAF_MAP;
    vcd->curstate.G1_charset    = GRAF_MAP;
    vcd->curstate.flags         = 0;
    vcd->curstate.flags         = 0;
    vcd->need_wrap              = 0;
    vcd->need_wrap              = 0;
    vcd->report_mouse           = 0;
    vcd->report_mouse           = 0;
    vcd->utf                    = 0;
    vcd->utf                    = 0;
    vcd->utf_count              = 0;
    vcd->utf_count              = 0;
    vcd->disp_ctrl              = 0;
    vcd->disp_ctrl              = 0;
    vcd->toggle_meta            = 0;
    vcd->toggle_meta            = 0;
    vcd->decscnm                = 0;
    vcd->decscnm                = 0;
    vcd->decom                  = 0;
    vcd->decom                  = 0;
    vcd->decawm                 = 1;
    vcd->decawm                 = 1;
    vcd->deccm                  = 1;
    vcd->deccm                  = 1;
    vcd->decim                  = 0;
    vcd->decim                  = 0;
    vcd->curstate.forecol       = 7;
    vcd->curstate.forecol       = 7;
    vcd->curstate.backcol       = 0;
    vcd->curstate.backcol       = 0;
    vcd->def_forecol            = 7;
    vcd->def_forecol            = 7;
    vcd->def_backcol            = 0;
    vcd->def_backcol            = 0;
    vcd->tab_stop[0]             = 0x01010100;
    vcd->tab_stop[0]             = 0x01010100;
    vcd->tab_stop[1]            =
    vcd->tab_stop[1]            =
    vcd->tab_stop[2]            =
    vcd->tab_stop[2]            =
    vcd->tab_stop[3]            =
    vcd->tab_stop[3]            =
    vcd->tab_stop[4]            = 0x01010101;
    vcd->tab_stop[4]            = 0x01010101;
 
 
    set_kbd (decarm);
    set_kbd (decarm);
    clr_kbd (decckm);
    clr_kbd (decckm);
    clr_kbd(kbdapplic);
    clr_kbd(kbdapplic);
    clr_kbd(lnm);
    clr_kbd(lnm);
 
 
    vt->kbd->lockstate          = 0;
    vt->kbd->lockstate          = 0;
    vt->kbd->ledmode            = LED_SHOW_FLAGS;
    vt->kbd->ledmode            = LED_SHOW_FLAGS;
    vt->kbd->ledflagstate       = vt->kbd->default_ledflagstate;
    vt->kbd->ledflagstate       = vt->kbd->default_ledflagstate;
    if (!initialising)
    if (!initialising)
        set_leds ();
        set_leds ();
 
 
    if (vcd->screen.palette_entries) {
    if (vcd->screen.palette_entries) {
        kfree (vcd->screen.palette_entries);
        kfree (vcd->screen.palette_entries);
        vcd->screen.palette_entries = 0;
        vcd->screen.palette_entries = 0;
    }
    }
 
 
    gotoxy (vcd, 0, 0);
    gotoxy (vcd, 0, 0);
    vcd->savedstate = vcd->curstate;
    vcd->savedstate = vcd->curstate;
    update_attr (vt);
    update_attr (vt);
 
 
    if (!initialising)
    if (!initialising)
        csi_J (vt, 2);
        csi_J (vt, 2);
}
}
 
 
 
 
static inline void update_palette(const struct vt * const vt)
static inline void update_palette(const struct vt * const vt)
{
{
        const unsigned long *palette_entries;
        const unsigned long *palette_entries;
        int i;
        int i;
 
 
        if (vt->vcd->screen.palette_entries || vt->vtd->vc_mode != KD_GRAPHICS)
        if (vt->vcd->screen.palette_entries || vt->vtd->vc_mode != KD_GRAPHICS)
                palette_entries = default_palette_entries;
                palette_entries = default_palette_entries;
        else
        else
                palette_entries = vt->vcd->screen.palette_entries;
                palette_entries = vt->vcd->screen.palette_entries;
 
 
        palette_setpixel(0);
        palette_setpixel(0);
        for (i = MAX_PIX; i > 3; i -= 4) {
        for (i = MAX_PIX; i > 3; i -= 4) {
                palette_write(*palette_entries++);
                palette_write(*palette_entries++);
                palette_write(*palette_entries++);
                palette_write(*palette_entries++);
                palette_write(*palette_entries++);
                palette_write(*palette_entries++);
                palette_write(*palette_entries++);
                palette_write(*palette_entries++);
        }
        }
        for (; i > 0; i--)
        for (; i > 0; i--)
                palette_write(*palette_entries++);
                palette_write(*palette_entries++);
}
}
 
 
void update_scrmem (const struct vt * const vt, int start, int length)
void update_scrmem (const struct vt * const vt, int start, int length)
{
{
        unsigned long p, pp, sx, sy, ex, ey;
        unsigned long p, pp, sx, sy, ex, ey;
        unsigned long *buffer;
        unsigned long *buffer;
 
 
        length += start;
        length += start;
        sy = start / vtdata.numcolumns;
        sy = start / vtdata.numcolumns;
        sx = start % vtdata.numcolumns;
        sx = start % vtdata.numcolumns;
        ey = length / vtdata.numcolumns;
        ey = length / vtdata.numcolumns;
        ex = length % vtdata.numcolumns;
        ex = length % vtdata.numcolumns;
 
 
        if (ey > vtdata.numrows)
        if (ey > vtdata.numrows)
                ey = vtdata.numrows;
                ey = vtdata.numrows;
 
 
        p = vt->vcd->screen.origin + sy * vtdata.screen.sizerow;
        p = vt->vcd->screen.origin + sy * vtdata.screen.sizerow;
        buffer = vt->vcd->buffer.buffer + start;
        buffer = vt->vcd->buffer.buffer + start;
 
 
        if (ey > sy) {
        if (ey > sy) {
                for (; sy < ey; sy++) {
                for (; sy < ey; sy++) {
                        pp = p + sx * vtdata.screen.bytespercharh;
                        pp = p + sx * vtdata.screen.bytespercharh;
                        for (; sx < vtdata.numcolumns; sx++) {
                        for (; sx < vtdata.numcolumns; sx++) {
                                ll_write_char (pp, *buffer++);
                                ll_write_char (pp, *buffer++);
                                pp += vtdata.screen.bytespercharh;
                                pp += vtdata.screen.bytespercharh;
                        }
                        }
                        p += vtdata.screen.sizerow;
                        p += vtdata.screen.sizerow;
                        sx = 0;
                        sx = 0;
                }
                }
        }
        }
 
 
        if (ey == sy && ex) {
        if (ey == sy && ex) {
                for (; sx < ex; sx++) {
                for (; sx < ex; sx++) {
                        ll_write_char (p, *buffer++);
                        ll_write_char (p, *buffer++);
                        p += vtdata.screen.bytespercharh;
                        p += vtdata.screen.bytespercharh;
                }
                }
        }
        }
}
}
 
 
void set_scrmem (const struct vt * const vt, long offset)
void set_scrmem (const struct vt * const vt, long offset)
{
{
    unsigned long p, pp, my, by;
    unsigned long p, pp, my, by;
    unsigned long *buffer;
    unsigned long *buffer;
 
 
    p = vt->vcd->screen.origin;
    p = vt->vcd->screen.origin;
    buffer = vt->vcd->buffer.buffer;
    buffer = vt->vcd->buffer.buffer;
 
 
    by = vtdata.screen.sizerow;
    by = vtdata.screen.sizerow;
    for (my = vtdata.numrows; my > 0; my--) {
    for (my = vtdata.numrows; my > 0; my--) {
        int mx, bx = vtdata.screen.bytespercharh;
        int mx, bx = vtdata.screen.bytespercharh;
        pp = p;
        pp = p;
        mx = vtdata.numcolumns;
        mx = vtdata.numcolumns;
        while (mx > 8) {
        while (mx > 8) {
            mx -= 8;
            mx -= 8;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
        }
        }
        while (mx > 0) {
        while (mx > 0) {
            mx -= 1;
            mx -= 1;
            ll_write_char (pp, *buffer++); pp += bx;
            ll_write_char (pp, *buffer++); pp += bx;
        }
        }
        p += by;
        p += by;
    }
    }
    pp = vt->vcd->screen.origin + vtdata.screen.memsize;
    pp = vt->vcd->screen.origin + vtdata.screen.memsize;
    memsetl((unsigned long *)p, vt->vcd->cached_backcolwrd, pp - p);
    memsetl((unsigned long *)p, vt->vcd->cached_backcolwrd, pp - p);
    update_palette(vt);
    update_palette(vt);
}
}
 
 
/*
/*
 * PIO_FONT support
 * PIO_FONT support
 */
 */
int con_set_font (char *arg)
int con_set_font (char *arg)
{
{
        return -EINVAL;
        return -EINVAL;
}
}
 
 
int con_get_font (char *arg)
int con_get_font (char *arg)
{
{
        return -EINVAL;
        return -EINVAL;
}
}
 
 
void con_reset_palette (const struct vt * const vt)
void con_reset_palette (const struct vt * const vt)
{
{
}
}
 
 
void con_set_palette (const struct vt * const vt)
void con_set_palette (const struct vt * const vt)
{
{
        update_palette(vt);
        update_palette(vt);
}
}
 
 
/* == arm specific console code ============================================================== */
/* == arm specific console code ============================================================== */
 
 
int do_screendump(int arg)
int do_screendump(int arg)
{
{
    char *buf = (char *)arg;
    char *buf = (char *)arg;
    int l;
    int l;
    if (!suser())
    if (!suser())
        return -EPERM;
        return -EPERM;
    l = verify_area (VERIFY_WRITE, buf, 2);
    l = verify_area (VERIFY_WRITE, buf, 2);
    if (l)
    if (l)
        return l;
        return l;
    return -ENOSYS;
    return -ENOSYS;
}
}
 
 
void vcd_disallocate (struct vt *vt)
void vcd_disallocate (struct vt *vt)
{
{
        if (vt->vcd && vt->vcd->buffer.kmalloced) {
        if (vt->vcd && vt->vcd->buffer.kmalloced) {
                vfree (vt->vcd->buffer.buffer);
                vfree (vt->vcd->buffer.buffer);
                vt->vcd->buffer.buffer = NULL;
                vt->vcd->buffer.buffer = NULL;
                vt->vcd->buffer.kmalloced = 0;
                vt->vcd->buffer.kmalloced = 0;
        }
        }
}
}
 
 
int vcd_resize(unsigned long lines, unsigned long cols)
int vcd_resize(unsigned long lines, unsigned long cols)
{/* TODO */
{/* TODO */
        return -ENOMEM;
        return -ENOMEM;
}
}
 
 
void vcd_blankscreen(int nopowersave)
void vcd_blankscreen(int nopowersave)
{
{
        unsigned int pix;
        unsigned int pix;
 
 
    /* DISABLE VIDEO */
    /* DISABLE VIDEO */
        palette_setpixel(0);
        palette_setpixel(0);
        for (pix = 0; pix < MAX_PIX; pix++)
        for (pix = 0; pix < MAX_PIX; pix++)
                palette_write(0);
                palette_write(0);
}
}
 
 
void vcd_unblankscreen (void)
void vcd_unblankscreen (void)
{
{
        update_palette(vtdata.fgconsole);
        update_palette(vtdata.fgconsole);
}
}
 
 
static unsigned long old_origin;
static unsigned long old_origin;
 
 
void vcd_savestate (const struct vt *vt, int blanked)
void vcd_savestate (const struct vt *vt, int blanked)
{
{
    struct con_struct *vcd = vt->vcd;
    struct con_struct *vcd = vt->vcd;
    clear_selection ();
    clear_selection ();
    vcd_removecursors (vt);
    vcd_removecursors (vt);
    old_origin = vt->vcd->screen.origin;
    old_origin = vt->vcd->screen.origin;
 
 
    if (blanked)
    if (blanked)
        vtdata.blanked = NULL;
        vtdata.blanked = NULL;
 
 
    memcpy (vcd->buffer.buffer, vtdata.buffer.buffer + vtdata.buffer.origin,
    memcpy (vcd->buffer.buffer, vtdata.buffer.buffer + vtdata.buffer.origin,
                vtdata.buffer.totsize << 2);
                vtdata.buffer.totsize << 2);
    vcd->buffer.pos -= vtdata.buffer.origin;
    vcd->buffer.pos -= vtdata.buffer.origin;
    vcd->driver = buffer_driver;
    vcd->driver = buffer_driver;
#ifdef DEBUG
#ifdef DEBUG
    vcd_validate (vt->vcd, "vcd_savestate");
    vcd_validate (vt->vcd, "vcd_savestate");
#endif
#endif
}
}
 
 
void vcd_restorestate (const struct vt *vt)
void vcd_restorestate (const struct vt *vt)
{
{
    struct con_struct *vcd = vt->vcd;
    struct con_struct *vcd = vt->vcd;
    int text_mode;
    int text_mode;
    /*
    /*
     * Reset the origin on this VT to be the same as the previous.
     * Reset the origin on this VT to be the same as the previous.
     * This way we don't get any jumps when we change VT's.
     * This way we don't get any jumps when we change VT's.
     */
     */
    text_mode = vt->vtd->vc_mode == KD_TEXT ? 1 : 0;
    text_mode = vt->vtd->vc_mode == KD_TEXT ? 1 : 0;
    memcpy (vtdata.buffer.buffer, vcd->buffer.buffer, vtdata.buffer.totsize << 2);
    memcpy (vtdata.buffer.buffer, vcd->buffer.buffer, vtdata.buffer.totsize << 2);
    vtdata.buffer.origin = 0;
    vtdata.buffer.origin = 0;
    if (text_mode) {
    if (text_mode) {
        vt->vcd->screen.origin = old_origin;
        vt->vcd->screen.origin = old_origin;
        set_scrmem (vt, 0);
        set_scrmem (vt, 0);
    } else
    } else
        vt->vcd->screen.origin = SCREEN2_BASE;
        vt->vcd->screen.origin = SCREEN2_BASE;
    vcd->driver = screen_driver;
    vcd->driver = screen_driver;
    gotoxy(vt->vcd, vt->vcd->curstate.x, vt->vcd->curstate.y);
    gotoxy(vt->vcd, vt->vcd->curstate.x, vt->vcd->curstate.y);
#ifdef DEBUG
#ifdef DEBUG
    vcd_validate (vt->vcd, "vcd_restorestate");
    vcd_validate (vt->vcd, "vcd_restorestate");
#endif
#endif
    set_origin(vt);
    set_origin(vt);
    set_cursor(vt);
    set_cursor(vt);
    if (text_mode)
    if (text_mode)
        vcd_restorecursors (vt);
        vcd_restorecursors (vt);
    set_leds ();
    set_leds ();
}
}
 
 
void vcd_setup_graphics (const struct vt *vt)
void vcd_setup_graphics (const struct vt *vt)
{
{
    clear_selection ();
    clear_selection ();
    vcd_removecursors (vt);
    vcd_removecursors (vt);
    __set_origin (vtdata.screen.memstart);
    __set_origin (vtdata.screen.memstart);
}
}
 
 
/*===============================================================================================*/
/*===============================================================================================*/
 
 
static int vcd_write_utf (struct con_struct *vcd, int c)
static int vcd_write_utf (struct con_struct *vcd, int c)
{
{
    /* Combine UTF-8 into Unicode */
    /* Combine UTF-8 into Unicode */
    /* Incomplete characters silently ignored */
    /* Incomplete characters silently ignored */
    if (c < 0x80) {
    if (c < 0x80) {
        vcd->utf_count = 0;
        vcd->utf_count = 0;
        return c;
        return c;
    }
    }
 
 
    if (vcd->utf_count > 0 && (c & 0xc0) == 0x80) {
    if (vcd->utf_count > 0 && (c & 0xc0) == 0x80) {
        vcd->utf_char = (vcd->utf_char << 6) | (c & 0x3f);
        vcd->utf_char = (vcd->utf_char << 6) | (c & 0x3f);
        if (--vcd->utf_count == 0)
        if (--vcd->utf_count == 0)
            return vcd->utf_char;
            return vcd->utf_char;
        else
        else
            return -1;
            return -1;
    } else {
    } else {
        unsigned int count, chr;
        unsigned int count, chr;
        if ((c & 0xe0) == 0xc0) {
        if ((c & 0xe0) == 0xc0) {
            count = 1;
            count = 1;
            chr = (c & 0x1f);
            chr = (c & 0x1f);
        } else if ((c & 0xf0) == 0xe0) {
        } else if ((c & 0xf0) == 0xe0) {
            count = 2;
            count = 2;
            chr = (c & 0x0f);
            chr = (c & 0x0f);
        } else if ((c & 0xf8) == 0xf0) {
        } else if ((c & 0xf8) == 0xf0) {
            count = 3;
            count = 3;
            chr = (c & 0x07);
            chr = (c & 0x07);
        } else if ((c & 0xfc) == 0xf8) {
        } else if ((c & 0xfc) == 0xf8) {
            count = 4;
            count = 4;
            chr = (c & 0x03);
            chr = (c & 0x03);
        } else if ((c & 0xfe) == 0xfc) {
        } else if ((c & 0xfe) == 0xfc) {
            count = 5;
            count = 5;
            chr = (c & 0x01);
            chr = (c & 0x01);
        } else {
        } else {
            count = 0;
            count = 0;
            chr = 0;
            chr = 0;
        }
        }
        vcd->utf_count = count;
        vcd->utf_count = count;
        vcd->utf_char = chr;
        vcd->utf_char = chr;
        return -1;
        return -1;
    }
    }
}
}
 
 
static int vcd_write_ctrl (const struct vt *vt, unsigned int c)
static int vcd_write_ctrl (const struct vt *vt, unsigned int c)
{
{
    struct con_struct *vcd = vt->vcd;
    struct con_struct *vcd = vt->vcd;
    /*
    /*
     *  Control characters can be used in the _middle_
     *  Control characters can be used in the _middle_
     *  of an escape sequence.
     *  of an escape sequence.
     */
     */
    switch (c) {
    switch (c) {
    case 0:
    case 0:
        return 0;
        return 0;
    case 7:
    case 7:
        if (vcd->bell_duration)
        if (vcd->bell_duration)
                vt_mksound (vcd->bell_pitch, 72, vcd->bell_duration);
                vt_mksound (vcd->bell_pitch, 72, vcd->bell_duration);
        return 0;
        return 0;
    case 8:
    case 8:
        if (vcd->need_wrap)
        if (vcd->need_wrap)
            vcd->need_wrap = 0;
            vcd->need_wrap = 0;
        else if (vcd->curstate.x) {
        else if (vcd->curstate.x) {
            vcd->curstate.x --;
            vcd->curstate.x --;
            if (vtdata.fgconsole == vt)
            if (vtdata.fgconsole == vt)
                vcd->screen.pos -= vtdata.screen.bytespercharh;
                vcd->screen.pos -= vtdata.screen.bytespercharh;
            vcd->buffer.pos -= 1;
            vcd->buffer.pos -= 1;
            vcd->need_wrap = 0;
            vcd->need_wrap = 0;
        }
        }
        return 0;
        return 0;
    case 9:
    case 9:
        if (vtdata.fgconsole == vt)
        if (vtdata.fgconsole == vt)
            vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
            vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
        vcd->buffer.pos -= vcd->curstate.x;
        vcd->buffer.pos -= vcd->curstate.x;
        while (vcd->curstate.x < vtdata.numcolumns - 1) {
        while (vcd->curstate.x < vtdata.numcolumns - 1) {
            vcd->curstate.x++;
            vcd->curstate.x++;
            if (vcd->tab_stop[vcd->curstate.x >> 5] & (1 << (vcd->curstate.x & 31)))
            if (vcd->tab_stop[vcd->curstate.x >> 5] & (1 << (vcd->curstate.x & 31)))
                break;
                break;
        }
        }
        if (vtdata.fgconsole == vt)
        if (vtdata.fgconsole == vt)
            vcd->screen.pos += vcd->curstate.x * vtdata.screen.bytespercharh;
            vcd->screen.pos += vcd->curstate.x * vtdata.screen.bytespercharh;
        vcd->buffer.pos += vcd->curstate.x;
        vcd->buffer.pos += vcd->curstate.x;
        return 0;
        return 0;
    case 10:
    case 10:
    case 11:
    case 11:
    case 12:
    case 12:
        if (vcd->curstate.y + 1 == vcd->bottom)
        if (vcd->curstate.y + 1 == vcd->bottom)
            vcd->driver.scroll_up (vcd, vcd->top, vcd->bottom, 1);
            vcd->driver.scroll_up (vcd, vcd->top, vcd->bottom, 1);
        else if (vcd->curstate.y < vtdata.numrows - 1) {
        else if (vcd->curstate.y < vtdata.numrows - 1) {
            vcd->curstate.y ++;
            vcd->curstate.y ++;
            if (vtdata.fgconsole == vt)
            if (vtdata.fgconsole == vt)
                vcd->screen.pos += vtdata.screen.sizerow;
                vcd->screen.pos += vtdata.screen.sizerow;
            vcd->buffer.pos += vtdata.buffer.sizerow;
            vcd->buffer.pos += vtdata.buffer.sizerow;
        }
        }
        vcd->need_wrap = 0;
        vcd->need_wrap = 0;
        if (!is_kbd(lnm))
        if (!is_kbd(lnm))
            return 0;
            return 0;
    case 13:
    case 13:
        if (vtdata.fgconsole == vt)
        if (vtdata.fgconsole == vt)
            vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
            vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
        vcd->buffer.pos -= vcd->curstate.x;
        vcd->buffer.pos -= vcd->curstate.x;
        vcd->curstate.x = vcd->need_wrap = 0;
        vcd->curstate.x = vcd->need_wrap = 0;
        return 0;
        return 0;
    case 14:
    case 14:
        vcd->curstate.flags |= FLG_CHRSET;
        vcd->curstate.flags |= FLG_CHRSET;
        vcd->disp_ctrl = 1;
        vcd->disp_ctrl = 1;
        vcd->translate = set_translate(vcd->curstate.G1_charset);
        vcd->translate = set_translate(vcd->curstate.G1_charset);
        return 1;
        return 1;
    case 15:
    case 15:
        vcd->curstate.flags &= ~FLG_CHRSET;
        vcd->curstate.flags &= ~FLG_CHRSET;
        vcd->disp_ctrl = 0;
        vcd->disp_ctrl = 0;
        vcd->translate = set_translate(vcd->curstate.G0_charset);
        vcd->translate = set_translate(vcd->curstate.G0_charset);
        return 1;
        return 1;
    case 24:
    case 24:
    case 26:
    case 26:
        vcd->state = ESnormal;
        vcd->state = ESnormal;
        return 0;
        return 0;
    case 27:
    case 27:
        vcd->state = ESesc;
        vcd->state = ESesc;
        return 0;
        return 0;
    case 127:
    case 127:
        /* ignored */
        /* ignored */
        return 0;
        return 0;
    case 128+27:
    case 128+27:
        vcd->state = ESsquare;
        vcd->state = ESsquare;
        return 0;
        return 0;
    }
    }
 
 
    switch(vcd->state) {
    switch(vcd->state) {
    case ESesc:
    case ESesc:
        vcd->state = ESnormal;
        vcd->state = ESnormal;
        switch (c) {
        switch (c) {
        case '[':
        case '[':
            vcd->state = ESsquare;
            vcd->state = ESsquare;
            break;
            break;
        case ']':
        case ']':
            vcd->state = ESnonstd;
            vcd->state = ESnonstd;
            break;
            break;
        case '%':
        case '%':
            vcd->state = ESpercent;
            vcd->state = ESpercent;
            break;
            break;
        case 'E':
        case 'E':
            if (vtdata.fgconsole == vt)
            if (vtdata.fgconsole == vt)
                vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
                vcd->screen.pos -= vcd->curstate.x * vtdata.screen.bytespercharh;
            vcd->buffer.pos -= vcd->curstate.x;
            vcd->buffer.pos -= vcd->curstate.x;
            vcd->curstate.x = vcd->need_wrap = 0;
            vcd->curstate.x = vcd->need_wrap = 0;
        case 'D':
        case 'D':
            if (vcd->curstate.y + 1 == vcd->bottom)
            if (vcd->curstate.y + 1 == vcd->bottom)
                vcd->driver.scroll_up (vcd, vcd->top, vcd->bottom, 1);
                vcd->driver.scroll_up (vcd, vcd->top, vcd->bottom, 1);
            else if (vcd->curstate.y < vtdata.numrows - 1) {
            else if (vcd->curstate.y < vtdata.numrows - 1) {
                vcd->curstate.y ++;
                vcd->curstate.y ++;
                if (vtdata.fgconsole == vt)
                if (vtdata.fgconsole == vt)
                    vcd->screen.pos += vtdata.screen.sizerow;
                    vcd->screen.pos += vtdata.screen.sizerow;
                vcd->buffer.pos += vtdata.buffer.sizerow;
                vcd->buffer.pos += vtdata.buffer.sizerow;
            }
            }
            /* vcd->need_wrap = 0; why should we reset this when the x position is the same? */
            /* vcd->need_wrap = 0; why should we reset this when the x position is the same? */
            break;
            break;
        case 'M':
        case 'M':
            if (vcd->curstate.y == vcd->top)
            if (vcd->curstate.y == vcd->top)
                vcd->driver.scroll_down (vcd, vcd->top, vcd->bottom, 1);
                vcd->driver.scroll_down (vcd, vcd->top, vcd->bottom, 1);
            else if (vcd->curstate.y > 0) {
            else if (vcd->curstate.y > 0) {
                vcd->curstate.y --;
                vcd->curstate.y --;
                if (vtdata.fgconsole == vt)
                if (vtdata.fgconsole == vt)
                    vcd->screen.pos -= vtdata.screen.sizerow;
                    vcd->screen.pos -= vtdata.screen.sizerow;
                vcd->buffer.pos -= vtdata.buffer.sizerow;
                vcd->buffer.pos -= vtdata.buffer.sizerow;
            }
            }
            /* vcd->need_wrap = 0; why should we reset this when the x position is the same? */
            /* vcd->need_wrap = 0; why should we reset this when the x position is the same? */
            break;
            break;
        case 'H':
        case 'H':
            vcd->tab_stop[vcd->curstate.x >> 5] |= (1 << (vcd->curstate.x & 31));
            vcd->tab_stop[vcd->curstate.x >> 5] |= (1 << (vcd->curstate.x & 31));
            break;
            break;
        case 'Z':
        case 'Z':
            respond_ID (*vt->tty);
            respond_ID (*vt->tty);
            break;
            break;
        case '7':
        case '7':
            vcd->savedstate = vcd->curstate;
            vcd->savedstate = vcd->curstate;
            break;
            break;
        case '8':
        case '8':
            vcd->curstate = vcd->savedstate;
            vcd->curstate = vcd->savedstate;
            gotoxy(vt->vcd, vt->vcd->curstate.x, vt->vcd->curstate.y);
            gotoxy(vt->vcd, vt->vcd->curstate.x, vt->vcd->curstate.y);
            update_attr (vt);
            update_attr (vt);
            return 1;
            return 1;
        case '(':
        case '(':
            vcd->state = ESsetG0;
            vcd->state = ESsetG0;
            break;
            break;
        case ')':
        case ')':
            vcd->state = ESsetG1;
            vcd->state = ESsetG1;
            break;
            break;
        case '#':
        case '#':
            vcd->state = EShash;
            vcd->state = EShash;
            break;
            break;
        case 'c':
        case 'c':
            reset_terminal (vt, 0);
            reset_terminal (vt, 0);
            break;
            break;
        case '>': /* Numeric keypad */
        case '>': /* Numeric keypad */
            clr_kbd (kbdapplic);
            clr_kbd (kbdapplic);
            break;
            break;
        case '=': /* Appl. keypad */
        case '=': /* Appl. keypad */
            set_kbd (kbdapplic);
            set_kbd (kbdapplic);
            break;
            break;
        }
        }
        return 0;
        return 0;
    case ESnonstd:
    case ESnonstd:
        vcd->state = ESnormal;
        vcd->state = ESnormal;
        switch (c) {
        switch (c) {
        case 'P': /* palette escape sequence */
        case 'P': /* palette escape sequence */
            for (vcd->npar = 0; vcd->npar < NPAR; vcd->npar++)
            for (vcd->npar = 0; vcd->npar < NPAR; vcd->npar++)
                vcd->par[vcd->npar] = 0;
                vcd->par[vcd->npar] = 0;
            vcd->npar = 0 ;
            vcd->npar = 0 ;
            vcd->state = ESpalette;
            vcd->state = ESpalette;
            return 0;
            return 0;
        case 'R': /* reset palette */
        case 'R': /* reset palette */
            con_reset_palette (vt);
            con_reset_palette (vt);
        default:
        default:
            return 0;
            return 0;
        }
        }
    case ESpalette:
    case ESpalette:
        if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) {
        if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) {
            vcd->par[vcd->npar++] = (c > '9' ? (c & 0xDF) - 'A' + 10 : c - '0');
            vcd->par[vcd->npar++] = (c > '9' ? (c & 0xDF) - 'A' + 10 : c - '0');
            if (vcd->npar == 7) {
            if (vcd->npar == 7) {
#if TODO
#if TODO
                int i = par[0]*3, j = 1;
                int i = par[0]*3, j = 1;
                palette[i] = 16*par[j++];
                palette[i] = 16*par[j++];
                palette[i++] += par[j++];
                palette[i++] += par[j++];
                palette[i] = 16*par[j++];
                palette[i] = 16*par[j++];
                palette[i++] += par[j++];
                palette[i++] += par[j++];
                palette[i] = 16*par[j++];
                palette[i] = 16*par[j++];
                palette[i++] += par[j];
                palette[i++] += par[j];
#endif
#endif
                con_set_palette (vt);
                con_set_palette (vt);
                vcd->state = ESnormal;
                vcd->state = ESnormal;
            }
            }
        } else
        } else
            vcd->state = ESnormal;
            vcd->state = ESnormal;
        return 0;
        return 0;
    case ESsquare:
    case ESsquare:
        for (vcd->npar = 0; vcd->npar < NPAR; vcd->npar++)
        for (vcd->npar = 0; vcd->npar < NPAR; vcd->npar++)
            vcd->par[vcd->npar] = 0;
            vcd->par[vcd->npar] = 0;
        vcd->npar = 0;
        vcd->npar = 0;
        vcd->state = ESgetpars;
        vcd->state = ESgetpars;
        if (c == '[') { /* Function key */
        if (c == '[') { /* Function key */
            vcd->state = ESfunckey;
            vcd->state = ESfunckey;
            return 0;
            return 0;
        }
        }
 
 
        vcd->ques = (c == '?');
        vcd->ques = (c == '?');
        if (vcd->ques)
        if (vcd->ques)
            return 0;
            return 0;
    case ESgetpars:
    case ESgetpars:
        if (c == ';' && vcd->npar < NPAR - 1) {
        if (c == ';' && vcd->npar < NPAR - 1) {
            vcd->npar ++;
            vcd->npar ++;
            return 0;
            return 0;
        } else
        } else
        if (c >= '0' && c <= '9') {
        if (c >= '0' && c <= '9') {
            vcd->par[vcd->npar] = vcd->par[vcd->npar] * 10 + c - '0';
            vcd->par[vcd->npar] = vcd->par[vcd->npar] * 10 + c - '0';
            return 0;
            return 0;
        } else
        } else
            vcd->state = ESgotpars;
            vcd->state = ESgotpars;
    case ESgotpars:
    case ESgotpars:
        vcd->state=ESnormal;
        vcd->state=ESnormal;
        switch (c) {
        switch (c) {
        case 'h':
        case 'h':
            set_mode(vt, 1);
            set_mode(vt, 1);
            return 0;
            return 0;
        case 'l':
        case 'l':
            set_mode(vt, 0);
            set_mode(vt, 0);
            return 0;
            return 0;
        case 'n':
        case 'n':
            if (!vcd->ques) {
            if (!vcd->ques) {
                if (vcd->par[0] == 5)
                if (vcd->par[0] == 5)
                    status_report (*vt->tty);
                    status_report (*vt->tty);
                else
                else
                if (vcd->par[0] == 6)
                if (vcd->par[0] == 6)
                    cursor_report (vt);
                    cursor_report (vt);
            }
            }
            return 0;
            return 0;
        }
        }
        if (vcd->ques) {
        if (vcd->ques) {
                vcd->ques = 0;
                vcd->ques = 0;
                return 0;
                return 0;
        }
        }
        switch(c) {
        switch(c) {
        case 'G':
        case 'G':
        case '`':
        case '`':
            if (vcd->par[0])
            if (vcd->par[0])
                vcd->par[0]--;
                vcd->par[0]--;
            gotoxy (vcd, vcd->par[0], vcd->curstate.y);
            gotoxy (vcd, vcd->par[0], vcd->curstate.y);
            return 0;
            return 0;
        case 'A':
        case 'A':
            if (!vcd->par[0])
            if (!vcd->par[0])
                vcd->par[0]++;
                vcd->par[0]++;
            gotoxy (vcd, vcd->curstate.x, vcd->curstate.y - vcd->par[0]);
            gotoxy (vcd, vcd->curstate.x, vcd->curstate.y - vcd->par[0]);
            return 0;
            return 0;
        case 'B':
        case 'B':
        case 'e':
        case 'e':
            if (!vcd->par[0])
            if (!vcd->par[0])
                vcd->par[0]++;
                vcd->par[0]++;
            gotoxy (vcd, vcd->curstate.x, vcd->curstate.y + vcd->par[0]);
            gotoxy (vcd, vcd->curstate.x, vcd->curstate.y + vcd->par[0]);
            return 0;
            return 0;
        case 'C':
        case 'C':
        case 'a':
        case 'a':
            if (!vcd->par[0])
            if (!vcd->par[0])
                vcd->par[0]++;
                vcd->par[0]++;
            gotoxy (vcd, vcd->curstate.x + vcd->par[0], vcd->curstate.y);
            gotoxy (vcd, vcd->curstate.x + vcd->par[0], vcd->curstate.y);
            return 0;
            return 0;
        case 'D':
        case 'D':
            if (!vcd->par[0])
            if (!vcd->par[0])
                vcd->par[0]++;
                vcd->par[0]++;
            gotoxy (vcd, vcd->curstate.x - vcd->par[0], vcd->curstate.y);
            gotoxy (vcd, vcd->curstate.x - vcd->par[0], vcd->curstate.y);
            return 0;
            return 0;
        case 'E':
        case 'E':
            if (!vcd->par[0])
            if (!vcd->par[0])
                vcd->par[0]++;
                vcd->par[0]++;
            gotoxy (vcd, 0, vcd->curstate.y + vcd->par[0]);
            gotoxy (vcd, 0, vcd->curstate.y + vcd->par[0]);
            return 0;
            return 0;
        case 'F':
        case 'F':
            if (!vcd->par[0])
            if (!vcd->par[0])
                vcd->par[0]++;
                vcd->par[0]++;
            gotoxy (vcd, 0, vcd->curstate.y - vcd->par[0]);
            gotoxy (vcd, 0, vcd->curstate.y - vcd->par[0]);
            return 0;
            return 0;
        case 'd':
        case 'd':
            if (vcd->par[0])
            if (vcd->par[0])
                vcd->par[0]--;
                vcd->par[0]--;
            gotoxay (vcd, vcd->curstate.x, vcd->par[0]);
            gotoxay (vcd, vcd->curstate.x, vcd->par[0]);
            return 0;
            return 0;
        case 'H':
        case 'H':
        case 'f':
        case 'f':
            if (vcd->par[0])
            if (vcd->par[0])
                vcd->par[0]--;
                vcd->par[0]--;
            if (vcd->par[1])
            if (vcd->par[1])
                vcd->par[1]--;
                vcd->par[1]--;
            gotoxay (vcd, vcd->par[1], vcd->par[0]);
            gotoxay (vcd, vcd->par[1], vcd->par[0]);
            return 0;
            return 0;
        case 'J':
        case 'J':
            csi_J (vt, vcd->par[0]);
            csi_J (vt, vcd->par[0]);
            return 0;
            return 0;
        case 'K':
        case 'K':
            csi_K (vt, vcd->par[0]);
            csi_K (vt, vcd->par[0]);
            return 0;
            return 0;
        case 'L':
        case 'L':
            csi_L (vt, vcd->par[0]);
            csi_L (vt, vcd->par[0]);
            return 0;
            return 0;
        case 'M':
        case 'M':
            csi_M (vt, vcd->par[0]);
            csi_M (vt, vcd->par[0]);
            return 0;
            return 0;
        case 'P':
        case 'P':
            csi_P (vt, vcd->par[0]);
            csi_P (vt, vcd->par[0]);
            return 0;
            return 0;
        case 'c':
        case 'c':
            if (!vcd->par[0])
            if (!vcd->par[0])
                respond_ID(*vt->tty);
                respond_ID(*vt->tty);
            return 0;
            return 0;
        case 'g':
        case 'g':
            if (!vcd->par[0])
            if (!vcd->par[0])
                vcd->tab_stop[vcd->curstate.x >> 5] &= ~(1 << (vcd->curstate.x & 31));
                vcd->tab_stop[vcd->curstate.x >> 5] &= ~(1 << (vcd->curstate.x & 31));
            else
            else
            if (vcd->par[0] == 3) {
            if (vcd->par[0] == 3) {
                vcd->tab_stop[0] =
                vcd->tab_stop[0] =
                vcd->tab_stop[1] =
                vcd->tab_stop[1] =
                vcd->tab_stop[2] =
                vcd->tab_stop[2] =
                vcd->tab_stop[3] =
                vcd->tab_stop[3] =
                vcd->tab_stop[4] = 0;
                vcd->tab_stop[4] = 0;
            }
            }
            return 0;
            return 0;
        case 'm':
        case 'm':
            return csi_m (vt);
            return csi_m (vt);
        case 'q': /* DECLL - but only 3 leds */
        case 'q': /* DECLL - but only 3 leds */
            /* map 0,1,2,3 to 0,1,2,4 */
            /* map 0,1,2,3 to 0,1,2,4 */
            if (vcd->par[0] < 4)
            if (vcd->par[0] < 4)
                  setledstate(vt->kbd, (vcd->par[0] < 3 ? vcd->par[0] : 4));
                  setledstate(vt->kbd, (vcd->par[0] < 3 ? vcd->par[0] : 4));
            return 0;
            return 0;
        case 'r':
        case 'r':
            if (!vcd->par[0])
            if (!vcd->par[0])
                vcd->par[0]++;
                vcd->par[0]++;
            if (!vcd->par[1])
            if (!vcd->par[1])
                vcd->par[1] = vtdata.numrows;
                vcd->par[1] = vtdata.numrows;
            if (vcd->par[0] < vcd->par[1] && vcd->par[1] <= vtdata.numrows) {
            if (vcd->par[0] < vcd->par[1] && vcd->par[1] <= vtdata.numrows) {
                vcd->top = vcd->par[0] - 1;
                vcd->top = vcd->par[0] - 1;
                vcd->bottom = vcd->par[1];
                vcd->bottom = vcd->par[1];
                gotoxay (vcd, 0, 0);
                gotoxay (vcd, 0, 0);
            }
            }
            return 0;
            return 0;
        case 's':
        case 's':
            vcd->savedstate = vcd->curstate;
            vcd->savedstate = vcd->curstate;
            return 0;
            return 0;
        case 'u':
        case 'u':
            vcd->curstate = vcd->savedstate;
            vcd->curstate = vcd->savedstate;
            update_attr (vt);
            update_attr (vt);
            return 1;
            return 1;
        case 'X':
        case 'X':
            csi_X (vt, vcd->par[0]);
            csi_X (vt, vcd->par[0]);
            return 0;
            return 0;
        case '@':
        case '@':
            csi_at (vt, vcd->par[0]);
            csi_at (vt, vcd->par[0]);
            return 0;
            return 0;
        case ']': /* setterm functions */
        case ']': /* setterm functions */
            setterm_command (vt);
            setterm_command (vt);
            return 0;
            return 0;
        }
        }
        return 0;
        return 0;
    case ESpercent:
    case ESpercent:
        vcd->state = ESnormal;
        vcd->state = ESnormal;
        switch (c) {
        switch (c) {
        case '@': /* defined in ISO 2022 */
        case '@': /* defined in ISO 2022 */
            vcd->utf = 0;
            vcd->utf = 0;
            return 0;
            return 0;
        case 'G': /* prelim official escape code */
        case 'G': /* prelim official escape code */
        case '8': /* retained for compatibility */
        case '8': /* retained for compatibility */
            vcd->utf = 1;
            vcd->utf = 1;
            return 0;
            return 0;
        }
        }
        return 0;
        return 0;
    case ESfunckey:
    case ESfunckey:
        vcd->state = ESnormal;
        vcd->state = ESnormal;
        return 0;
        return 0;
    case EShash:
    case EShash:
        vcd->state = ESnormal;
        vcd->state = ESnormal;
        if (c == '8') {
        if (c == '8') {
            /* DEC screen alignment test. kludge :-) */
            /* DEC screen alignment test. kludge :-) */
        }
        }
        return 0;
        return 0;
    case ESsetG0:
    case ESsetG0:
        vcd->state = ESnormal;
        vcd->state = ESnormal;
        if (c == '0')
        if (c == '0')
            vcd->curstate.G0_charset = GRAF_MAP;
            vcd->curstate.G0_charset = GRAF_MAP;
        else
        else
        if (c == 'B')
        if (c == 'B')
            vcd->curstate.G0_charset = LAT1_MAP;
            vcd->curstate.G0_charset = LAT1_MAP;
        else
        else
        if (c == 'U')
        if (c == 'U')
            vcd->curstate.G0_charset = IBMPC_MAP;
            vcd->curstate.G0_charset = IBMPC_MAP;
        else
        else
        if (c == 'K')
        if (c == 'K')
            vcd->curstate.G0_charset = USER_MAP;
            vcd->curstate.G0_charset = USER_MAP;
        if ((vcd->curstate.flags & FLG_CHRSET) == 0) {
        if ((vcd->curstate.flags & FLG_CHRSET) == 0) {
            vcd->translate = set_translate(vcd->curstate.G0_charset);
            vcd->translate = set_translate(vcd->curstate.G0_charset);
            return 1;
            return 1;
        }
        }
        return 0;
        return 0;
    case ESsetG1:
    case ESsetG1:
        vcd->state = ESnormal;
        vcd->state = ESnormal;
        if (c == '0')
        if (c == '0')
            vcd->curstate.G1_charset = GRAF_MAP;
            vcd->curstate.G1_charset = GRAF_MAP;
        else
        else
        if (c == 'B')
        if (c == 'B')
            vcd->curstate.G1_charset = LAT1_MAP;
            vcd->curstate.G1_charset = LAT1_MAP;
        else
        else
        if (c == 'U')
        if (c == 'U')
            vcd->curstate.G1_charset = IBMPC_MAP;
            vcd->curstate.G1_charset = IBMPC_MAP;
        else
        else
        if (c == 'K')
        if (c == 'K')
            vcd->curstate.G1_charset = USER_MAP;
            vcd->curstate.G1_charset = USER_MAP;
        if (vcd->curstate.flags & FLG_CHRSET) {
        if (vcd->curstate.flags & FLG_CHRSET) {
            vcd->translate = set_translate(vcd->curstate.G1_charset);
            vcd->translate = set_translate(vcd->curstate.G1_charset);
            return 1;
            return 1;
        }
        }
        return 0;
        return 0;
    default:
    default:
        vcd->state = ESnormal;
        vcd->state = ESnormal;
    }
    }
    return 0;
    return 0;
}
}
 
 
static inline void vcd_write_char (struct con_struct *vcd, unsigned int c)
static inline void vcd_write_char (struct con_struct *vcd, unsigned int c)
{
{
    if (c & ~console_charmask)
    if (c & ~console_charmask)
        return;
        return;
    vcd->driver.write_char (vcd, vcd->combined_state | (c & 255));
    vcd->driver.write_char (vcd, vcd->combined_state | (c & 255));
}
}
 
 
int vcd_write (const struct vt *vt, int from_user, const unsigned char *buf, int count)
int vcd_write (const struct vt *vt, int from_user, const unsigned char *buf, int count)
{
{
    int strt_count = count;
    int strt_count = count;
    unsigned short *cached_trans;
    unsigned short *cached_trans;
    unsigned int cached_ctrls;
    unsigned int cached_ctrls;
    register struct con_struct *vcd;
    register struct con_struct *vcd;
 
 
    if (from_user && get_fs () == KERNEL_DS)
    if (from_user && get_fs () == KERNEL_DS)
        from_user = 0;
        from_user = 0;
 
 
    vcd = vt->vcd;
    vcd = vt->vcd;
 
 
#ifdef DEBUG
#ifdef DEBUG
    vcd_validate (vcd, "vcd_write entry");
    vcd_validate (vcd, "vcd_write entry");
#endif
#endif
 
 
    vcd_removecursors (vt);
    vcd_removecursors (vt);
    if (vt == vtdata.select.vt)
    if (vt == vtdata.select.vt)
        clear_selection();
        clear_selection();
 
 
    disable_bh (CONSOLE_BH);
    disable_bh (CONSOLE_BH);
recache:
recache:
    cached_ctrls = vcd->disp_ctrl ? CTRL_ALWAYS : CTRL_ACTION;
    cached_ctrls = vcd->disp_ctrl ? CTRL_ALWAYS : CTRL_ACTION;
    cached_trans = vcd->translate + (vcd->toggle_meta ? 0x80 : 0);
    cached_trans = vcd->translate + (vcd->toggle_meta ? 0x80 : 0);
 
 
    while (!(*vt->tty)->stopped && count) {
    while (!(*vt->tty)->stopped && count) {
        int tc, c;
        int tc, c;
        enable_bh(CONSOLE_BH);
        enable_bh(CONSOLE_BH);
        __asm__("teq    %3, #0
        __asm__("teq    %3, #0
        ldreqb  %0, [%1], #1
        ldreqb  %0, [%1], #1
        ldrnebt %0, [%1], #1" : "=r" (c), "=&r" (buf) : "1" (buf), "r" (from_user));
        ldrnebt %0, [%1], #1" : "=r" (c), "=&r" (buf) : "1" (buf), "r" (from_user));
        disable_bh(CONSOLE_BH);
        disable_bh(CONSOLE_BH);
        count --;
        count --;
 
 
        if (vcd->utf) {
        if (vcd->utf) {
            if ((tc = vcd_write_utf (vcd, c)) < 0)
            if ((tc = vcd_write_utf (vcd, c)) < 0)
                continue;
                continue;
            c = tc;
            c = tc;
        } else
        } else
            tc = cached_trans[c];
            tc = cached_trans[c];
 
 
        if (vcd->state == ESnormal && tc && (c != 127 || vcd->disp_ctrl) && (c != 128+27)) {
        if (vcd->state == ESnormal && tc && (c != 127 || vcd->disp_ctrl) && (c != 128+27)) {
            if (c >= 32 || (!vcd->utf && !(cached_ctrls & (1 << c)))) { /* ok */
            if (c >= 32 || (!vcd->utf && !(cached_ctrls & (1 << c)))) { /* ok */
                tc = conv_uni_to_pc (tc);
                tc = conv_uni_to_pc (tc);
                if (tc == -4)
                if (tc == -4)
                    /* If we got -4 (not found) then see if we have
                    /* If we got -4 (not found) then see if we have
                       defined a replacement character (U+FFFD) */
                       defined a replacement character (U+FFFD) */
                    tc = conv_uni_to_pc (0xfffd);
                    tc = conv_uni_to_pc (0xfffd);
                else if (tc == -3)
                else if (tc == -3)
                    /* Bad hash table -- hope for the best */
                    /* Bad hash table -- hope for the best */
                    tc = c;
                    tc = c;
 
 
                vcd_write_char (vcd, tc);
                vcd_write_char (vcd, tc);
                continue;
                continue;
            }
            }
        }
        }
 
 
        if (vcd_write_ctrl (vt, c))
        if (vcd_write_ctrl (vt, c))
            goto recache;
            goto recache;
        else
        else
            continue;
            continue;
    }
    }
    if (vt->vtd->vc_mode != KD_GRAPHICS)
    if (vt->vtd->vc_mode != KD_GRAPHICS)
        set_cursor (vt);
        set_cursor (vt);
    vcd_restorecursors (vt);
    vcd_restorecursors (vt);
    enable_bh(CONSOLE_BH);
    enable_bh(CONSOLE_BH);
#ifdef DEBUG
#ifdef DEBUG
    vcd_validate (vcd, "vcd_write exit");
    vcd_validate (vcd, "vcd_write exit");
#endif
#endif
    return strt_count - count;
    return strt_count - count;
}
}
 
 
int vcd_ioctl (const struct vt *vt, int cmd, unsigned long arg)
int vcd_ioctl (const struct vt *vt, int cmd, unsigned long arg)
{
{
    int i;
    int i;
    switch (cmd) {
    switch (cmd) {
    case VT_GETPALETTE: {
    case VT_GETPALETTE: {
        unsigned long pix, num, *ptr;
        unsigned long pix, num, *ptr;
        const unsigned long *entries;
        const unsigned long *entries;
 
 
        ptr = (unsigned long *)arg;
        ptr = (unsigned long *)arg;
 
 
        if ((i = verify_area (VERIFY_READ, ptr, 12)) != 0)
        if ((i = verify_area (VERIFY_READ, ptr, 12)) != 0)
                return i;
                return i;
 
 
        pix = get_user (ptr);
        pix = get_user (ptr);
        num = get_user (ptr + 1);
        num = get_user (ptr + 1);
        if (!num)
        if (!num)
                return 0;
                return 0;
        if (pix > 255 || pix + num > 256)
        if (pix > 255 || pix + num > 256)
                return -EINVAL;
                return -EINVAL;
 
 
        ptr = (unsigned long *) get_user (ptr + 2);
        ptr = (unsigned long *) get_user (ptr + 2);
        if ((i = verify_area (VERIFY_WRITE, ptr, num * sizeof (unsigned long))) != 0)
        if ((i = verify_area (VERIFY_WRITE, ptr, num * sizeof (unsigned long))) != 0)
                return i;
                return i;
 
 
        if (vt->vcd->screen.palette_entries)
        if (vt->vcd->screen.palette_entries)
                entries = vt->vcd->screen.palette_entries + pix;
                entries = vt->vcd->screen.palette_entries + pix;
        else
        else
                entries = default_palette_entries + pix;
                entries = default_palette_entries + pix;
        memcpy_tofs(ptr, entries, num * sizeof (unsigned long));
        memcpy_tofs(ptr, entries, num * sizeof (unsigned long));
        return 0;
        return 0;
        }
        }
    case VT_SETPALETTE: {
    case VT_SETPALETTE: {
        unsigned long pix, num, *ptr, *sval;
        unsigned long pix, num, *ptr, *sval;
 
 
        ptr = (unsigned long *)arg;
        ptr = (unsigned long *)arg;
 
 
        if ((i = verify_area (VERIFY_READ, ptr, 12)) != 0)
        if ((i = verify_area (VERIFY_READ, ptr, 12)) != 0)
                return i;
                return i;
 
 
        pix = get_user (ptr);
        pix = get_user (ptr);
        num = get_user (ptr + 1);
        num = get_user (ptr + 1);
        if (!num)
        if (!num)
                return 0;
                return 0;
        if (pix > 255 || pix + num > 256)
        if (pix > 255 || pix + num > 256)
                return -EINVAL;
                return -EINVAL;
 
 
        ptr = (unsigned long *) get_user (ptr + 2);
        ptr = (unsigned long *) get_user (ptr + 2);
        if ((i = verify_area (VERIFY_READ, ptr, num * sizeof (unsigned long))) != 0)
        if ((i = verify_area (VERIFY_READ, ptr, num * sizeof (unsigned long))) != 0)
                return i;
                return i;
 
 
        if (!vt->vcd->screen.palette_entries) {
        if (!vt->vcd->screen.palette_entries) {
                void *entries;
                void *entries;
                entries = kmalloc (sizeof (unsigned long) * 256, GFP_KERNEL);
                entries = kmalloc (sizeof (unsigned long) * 256, GFP_KERNEL);
                if (!vt->vcd->screen.palette_entries) {
                if (!vt->vcd->screen.palette_entries) {
                        if (!entries)
                        if (!entries)
                                return -ENOMEM;
                                return -ENOMEM;
                        memcpy (entries, default_palette_entries, 256 * sizeof (unsigned long));
                        memcpy (entries, default_palette_entries, 256 * sizeof (unsigned long));
                        vt->vcd->screen.palette_entries = entries;
                        vt->vcd->screen.palette_entries = entries;
                }
                }
        }
        }
        sval = vt->vcd->screen.palette_entries + pix;
        sval = vt->vcd->screen.palette_entries + pix;
        memcpy_fromfs (sval, ptr, num * sizeof (unsigned long));
        memcpy_fromfs (sval, ptr, num * sizeof (unsigned long));
        palette_setpixel(pix);
        palette_setpixel(pix);
        for (i = num; i > 3; i -= 4) {
        for (i = num; i > 3; i -= 4) {
            palette_write (*sval++);
            palette_write (*sval++);
            palette_write (*sval++);
            palette_write (*sval++);
            palette_write (*sval++);
            palette_write (*sval++);
            palette_write (*sval++);
            palette_write (*sval++);
        }
        }
        if (i & 2) {
        if (i & 2) {
            palette_write (*sval++);
            palette_write (*sval++);
            palette_write (*sval++);
            palette_write (*sval++);
        }
        }
        if (i & 1)
        if (i & 1)
            palette_write (*sval++);
            palette_write (*sval++);
        return 0;
        return 0;
        }
        }
 
 
    case PIO_FONT:
    case PIO_FONT:
        if (vt->vtd->vc_mode != KD_TEXT)
        if (vt->vtd->vc_mode != KD_TEXT)
            return -EINVAL;
            return -EINVAL;
        return con_set_font((char *)arg);
        return con_set_font((char *)arg);
        /* con_set_font() defined in console.c */
        /* con_set_font() defined in console.c */
 
 
    case GIO_FONT:
    case GIO_FONT:
        if (vt->vtd->vc_mode != KD_TEXT)
        if (vt->vtd->vc_mode != KD_TEXT)
            return -EINVAL;
            return -EINVAL;
        return con_get_font((char *)arg);
        return con_get_font((char *)arg);
        /* con_get_font() defined in console.c */
        /* con_get_font() defined in console.c */
 
 
    case PIO_SCRNMAP:
    case PIO_SCRNMAP:
        return con_set_trans_old ((char *)arg);
        return con_set_trans_old ((char *)arg);
 
 
    case GIO_SCRNMAP:
    case GIO_SCRNMAP:
        return con_get_trans_old((char *)arg);
        return con_get_trans_old((char *)arg);
 
 
    case PIO_UNISCRNMAP:
    case PIO_UNISCRNMAP:
        return con_set_trans_new((short *)arg);
        return con_set_trans_new((short *)arg);
 
 
    case GIO_UNISCRNMAP:
    case GIO_UNISCRNMAP:
        return con_get_trans_new((short *)arg);
        return con_get_trans_new((short *)arg);
 
 
    case PIO_UNIMAPCLR: {
    case PIO_UNIMAPCLR: {
        struct unimapinit ui;
        struct unimapinit ui;
 
 
        i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct unimapinit));
        i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct unimapinit));
        if (i)
        if (i)
            return i;
            return i;
        memcpy_fromfs(&ui, (void *)arg, sizeof(struct unimapinit));
        memcpy_fromfs(&ui, (void *)arg, sizeof(struct unimapinit));
        con_clear_unimap(&ui);
        con_clear_unimap(&ui);
        return 0;
        return 0;
        }
        }
 
 
    case PIO_UNIMAP: {
    case PIO_UNIMAP: {
        i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct unimapdesc));
        i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct unimapdesc));
        if (i == 0) {
        if (i == 0) {
            struct unimapdesc *ud;
            struct unimapdesc *ud;
            u_short ct;
            u_short ct;
            struct unipair *list;
            struct unipair *list;
 
 
            ud = (struct unimapdesc *) arg;
            ud = (struct unimapdesc *) arg;
            ct = get_fs_word(&ud->entry_ct);
            ct = get_fs_word(&ud->entry_ct);
            list = (struct unipair *) get_fs_long(&ud->entries);
            list = (struct unipair *) get_fs_long(&ud->entries);
 
 
            i = verify_area(VERIFY_READ, (void *) list,
            i = verify_area(VERIFY_READ, (void *) list,
                        ct*sizeof(struct unipair));
                        ct*sizeof(struct unipair));
            if (!i)
            if (!i)
                return con_set_unimap(ct, list);
                return con_set_unimap(ct, list);
        }
        }
        return i;
        return i;
        }
        }
 
 
    case GIO_UNIMAP: {
    case GIO_UNIMAP: {
        i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct unimapdesc));
        i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct unimapdesc));
        if (i == 0) {
        if (i == 0) {
            struct unimapdesc *ud;
            struct unimapdesc *ud;
            u_short ct;
            u_short ct;
            struct unipair *list;
            struct unipair *list;
 
 
            ud = (struct unimapdesc *) arg;
            ud = (struct unimapdesc *) arg;
            ct = get_fs_word(&ud->entry_ct);
            ct = get_fs_word(&ud->entry_ct);
            list = (struct unipair *) get_fs_long(&ud->entries);
            list = (struct unipair *) get_fs_long(&ud->entries);
            if (ct)
            if (ct)
                i = verify_area(VERIFY_WRITE, (void *) list,
                i = verify_area(VERIFY_WRITE, (void *) list,
                        ct*sizeof(struct unipair));
                        ct*sizeof(struct unipair));
            if (!i)
            if (!i)
                return con_get_unimap(ct, &(ud->entry_ct), list);
                return con_get_unimap(ct, &(ud->entry_ct), list);
        }
        }
        return i;
        return i;
        }
        }
 
 
    default:
    default:
        return -ENOIOCTLCMD;
        return -ENOIOCTLCMD;
    }
    }
}
}
 
 
void console_print(const char *b)
void console_print(const char *b)
{
{
        static int printing = 0;
        static int printing = 0;
        struct vt *vt = vtdata.fgconsole;
        struct vt *vt = vtdata.fgconsole;
        struct con_struct * const vcd = vt->vcd;
        struct con_struct * const vcd = vt->vcd;
        unsigned char c;
        unsigned char c;
 
 
#ifdef DEBUG
#ifdef DEBUG
        vcd_validate (vcd, "console_print entry");
        vcd_validate (vcd, "console_print entry");
#endif
#endif
 
 
        if (!printable || printing || vt->vtd->vc_mode == KD_GRAPHICS)
        if (!printable || printing || vt->vtd->vc_mode == KD_GRAPHICS)
                return;  /* console not yet initialized */
                return;  /* console not yet initialized */
        printing = 1;
        printing = 1;
 
 
        if (!vt_allocated(vtdata.fgconsole)) {
        if (!vt_allocated(vtdata.fgconsole)) {
                /* impossible */
                /* impossible */
                printk ("console_print: tty %d not allocated ??\n", vtdata.fgconsole->num);
                printk ("console_print: tty %d not allocated ??\n", vtdata.fgconsole->num);
                printing = 0;
                printing = 0;
                return;
                return;
        }
        }
 
 
#ifdef CONFIG_SERIAL_ECHO
#ifdef CONFIG_SERIAL_ECHO
        serial_echo_print (b);
        serial_echo_print (b);
#endif
#endif
        vcd_removecursors (vt);
        vcd_removecursors (vt);
        while ((c = *b++) != 0)
        while ((c = *b++) != 0)
                screen_driver.put_char(vcd, vcd->combined_state | (c & 255));
                screen_driver.put_char(vcd, vcd->combined_state | (c & 255));
        set_cursor (vt);
        set_cursor (vt);
        vcd_restorecursors (vt);
        vcd_restorecursors (vt);
 
 
        vt_pokeblankedconsole ();
        vt_pokeblankedconsole ();
        printing = 0;
        printing = 0;
#ifdef DEBUG
#ifdef DEBUG
        vcd_validate (vt->vcd, "console_print exit");
        vcd_validate (vt->vcd, "console_print exit");
#endif
#endif
}
}
 
 
/*===============================================================================================*/
/*===============================================================================================*/
 
 
int vcd_init (struct vt *vt, int kmallocok, unsigned long *kmem)
int vcd_init (struct vt *vt, int kmallocok, unsigned long *kmem)
{
{
        struct con_struct *vcd = vt->vcd;
        struct con_struct *vcd = vt->vcd;
        memset (vcd, 0, sizeof (*vcd));
        memset (vcd, 0, sizeof (*vcd));
 
 
        vcd->screen.origin              = vtdata.screen.memstart;
        vcd->screen.origin              = vtdata.screen.memstart;
        vcd->screen.cursoron            = (kmem ? 1 : 0);
        vcd->screen.cursoron            = (kmem ? 1 : 0);
        vcd->screen.palette_entries     = NULL;
        vcd->screen.palette_entries     = NULL;
        vcd->driver                     = buffer_driver;
        vcd->driver                     = buffer_driver;
        if (kmallocok) {
        if (kmallocok) {
                vcd->buffer.buffer      = vmalloc (vtdata.buffer.totsize * sizeof (unsigned long));
                vcd->buffer.buffer      = vmalloc (vtdata.buffer.totsize * sizeof (unsigned long));
                if (!vt->vcd->buffer.buffer)
                if (!vt->vcd->buffer.buffer)
                        return -ENOMEM;
                        return -ENOMEM;
                vcd->buffer.kmalloced   = 1;
                vcd->buffer.kmalloced   = 1;
        } else {
        } else {
                vcd->buffer.buffer      = (unsigned long *) *kmem;
                vcd->buffer.buffer      = (unsigned long *) *kmem;
                *kmem += vtdata.buffer.totsize * sizeof (unsigned long);
                *kmem += vtdata.buffer.totsize * sizeof (unsigned long);
        }
        }
 
 
        vt->vtd->paste_wait             = NULL;
        vt->vtd->paste_wait             = NULL;
        reset_terminal (vt, (kmem ? 1 : 0));
        reset_terminal (vt, (kmem ? 1 : 0));
        return 0;
        return 0;
}
}
 
 
/*
/*
 * We allow this irq to be shared
 * We allow this irq to be shared
 */
 */
static struct irqaction vsyncirq = { vsync_irq, SA_SHIRQ, 0, "vsync", NULL, NULL };
static struct irqaction vsyncirq = { vsync_irq, SA_SHIRQ, 0, "vsync", NULL, NULL };
 
 
unsigned long vcd_pre_init (unsigned long kmem, struct vt *vt)
unsigned long vcd_pre_init (unsigned long kmem, struct vt *vt)
{
{
        int colours, i;
        int colours, i;
 
 
        switch (bytes_per_char_h) {
        switch (bytes_per_char_h) {
        default:
        default:
        case 1:
        case 1:
                default_palette_entries = palette_1;
                default_palette_entries = palette_1;
                vtdata.screen.bytespercharh = 1;
                vtdata.screen.bytespercharh = 1;
                vtdata.screen.bitsperpix = 1;
                vtdata.screen.bitsperpix = 1;
                color_table = color_1;
                color_table = color_1;
                colours = 1;
                colours = 1;
                break;
                break;
        case 4:
        case 4:
                default_palette_entries = palette_4;
                default_palette_entries = palette_4;
                vtdata.screen.bytespercharh = 4;
                vtdata.screen.bytespercharh = 4;
                vtdata.screen.bitsperpix = 4;
                vtdata.screen.bitsperpix = 4;
                color_table = color_4;
                color_table = color_4;
                colours = 16;
                colours = 16;
                for (i = 0; i < 256; i++)
                for (i = 0; i < 256; i++)
                        con_charconvtable[i] =
                        con_charconvtable[i] =
                                (i & 128 ? 1 << 0  : 0) |
                                (i & 128 ? 1 << 0  : 0) |
                                (i & 64  ? 1 << 4  : 0) |
                                (i & 64  ? 1 << 4  : 0) |
                                (i & 32  ? 1 << 8  : 0) |
                                (i & 32  ? 1 << 8  : 0) |
                                (i & 16  ? 1 << 12 : 0) |
                                (i & 16  ? 1 << 12 : 0) |
                                (i & 8   ? 1 << 16 : 0) |
                                (i & 8   ? 1 << 16 : 0) |
                                (i & 4   ? 1 << 20 : 0) |
                                (i & 4   ? 1 << 20 : 0) |
                                (i & 2   ? 1 << 24 : 0) |
                                (i & 2   ? 1 << 24 : 0) |
                                (i & 1   ? 1 << 28 : 0);
                                (i & 1   ? 1 << 28 : 0);
                break;
                break;
        case 8:
        case 8:
                default_palette_entries = palette_8;
                default_palette_entries = palette_8;
                vtdata.screen.bytespercharh = 8;
                vtdata.screen.bytespercharh = 8;
                vtdata.screen.bitsperpix = 8;
                vtdata.screen.bitsperpix = 8;
                color_table = color_8;
                color_table = color_8;
                colours = 256;
                colours = 256;
                for (i = 0; i < 16; i++)
                for (i = 0; i < 16; i++)
                        con_charconvtable[i] =
                        con_charconvtable[i] =
                                (i & 8   ? 1 << 0  : 0) |
                                (i & 8   ? 1 << 0  : 0) |
                                (i & 4   ? 1 << 8  : 0) |
                                (i & 4   ? 1 << 8  : 0) |
                                (i & 2   ? 1 << 16 : 0) |
                                (i & 2   ? 1 << 16 : 0) |
                                (i & 1   ? 1 << 24 : 0);
                                (i & 1   ? 1 << 24 : 0);
                break;
                break;
        }
        }
        video_size_row          = vtdata.numcolumns * vtdata.screen.bytespercharh;
        video_size_row          = vtdata.numcolumns * vtdata.screen.bytespercharh;
        vtdata.screen.bytespercharv = bytes_per_char_v;
        vtdata.screen.bytespercharv = bytes_per_char_v;
        vtdata.screen.sizerow   = video_size_row * vtdata.screen.bytespercharv;
        vtdata.screen.sizerow   = video_size_row * vtdata.screen.bytespercharv;
        vtdata.screen.totsize   = vtdata.screen.sizerow * vtdata.numrows;
        vtdata.screen.totsize   = vtdata.screen.sizerow * vtdata.numrows;
 
 
        vtdata.screen.memsize   = ((vtdata.screen.totsize - 1) | (PAGE_SIZE - 1)) + 1;
        vtdata.screen.memsize   = ((vtdata.screen.totsize - 1) | (PAGE_SIZE - 1)) + 1;
        vtdata.screen.memend    = SCREEN1_END;
        vtdata.screen.memend    = SCREEN1_END;
        vtdata.screen.memstart  = vtdata.screen.memend - vtdata.screen.memsize;
        vtdata.screen.memstart  = vtdata.screen.memend - vtdata.screen.memsize;
        vtdata.buffer.buffer    = (unsigned long *)kmem;
        vtdata.buffer.buffer    = (unsigned long *)kmem;
        vtdata.buffer.sizerow   = vtdata.numcolumns;
        vtdata.buffer.sizerow   = vtdata.numcolumns;
        vtdata.buffer.totsize   = vtdata.numcolumns * vtdata.numrows;
        vtdata.buffer.totsize   = vtdata.numcolumns * vtdata.numrows;
        vtdata.buffer.lastorigin        = vtdata.buffer.totsize * 2;
        vtdata.buffer.lastorigin        = vtdata.buffer.totsize * 2;
        kmem = (unsigned long)(vtdata.buffer.buffer + vtdata.buffer.totsize * 3);
        kmem = (unsigned long)(vtdata.buffer.buffer + vtdata.buffer.totsize * 3);
        memzero (vtdata.buffer.buffer, vtdata.buffer.totsize * 3 << 2);
        memzero (vtdata.buffer.buffer, vtdata.buffer.totsize * 3 << 2);
 
 
        kmem = map_screen_mem (vtdata.screen.memstart, kmem, 1);
        kmem = map_screen_mem (vtdata.screen.memstart, kmem, 1);
 
 
        palette_setpixel(0);
        palette_setpixel(0);
        for (i = 0; i < MAX_PIX; i++)
        for (i = 0; i < MAX_PIX; i++)
                palette_write(default_palette_entries[i]);
                palette_write(default_palette_entries[i]);
 
 
        vcd_init (vt, 0, &kmem);
        vcd_init (vt, 0, &kmem);
        vt->vcd->driver = screen_driver;
        vt->vcd->driver = screen_driver;
 
 
        gotoxy (vt->vcd, ORIG_X, ORIG_Y);
        gotoxy (vt->vcd, ORIG_X, ORIG_Y);
        set_origin (vt);
        set_origin (vt);
        csi_J (vt, 0);
        csi_J (vt, 0);
        printable = 1;
        printable = 1;
 
 
#ifdef CONFIG_SERIAL_ECHO
#ifdef CONFIG_SERIAL_ECHO
        serial_echo_init (SERIAL_ECHO_PORT);
        serial_echo_init (SERIAL_ECHO_PORT);
#endif
#endif
        printk ("Console: %s %s %dx%dx%d, %d virtual console%s (max %d)\n",
        printk ("Console: %s %s %dx%dx%d, %d virtual console%s (max %d)\n",
                colours != 1 ? "colour" : "mono",
                colours != 1 ? "colour" : "mono",
                "A-series",
                "A-series",
                vtdata.numcolumns, vtdata.numrows, colours,
                vtdata.numcolumns, vtdata.numrows, colours,
                MIN_NR_CONSOLES,
                MIN_NR_CONSOLES,
                (MIN_NR_CONSOLES == 1) ? "":"s",
                (MIN_NR_CONSOLES == 1) ? "":"s",
                MAX_NR_CONSOLES);
                MAX_NR_CONSOLES);
 
 
        register_console (console_print);
        register_console (console_print);
 
 
        if (setup_arm_irq(IRQ_VSYNCPULSE, &vsyncirq))
        if (setup_arm_irq(IRQ_VSYNCPULSE, &vsyncirq))
                panic ("Unable to get VSYNC irq for console\n");
                panic ("Unable to get VSYNC irq for console\n");
 
 
        return kmem;
        return kmem;
}
}
 
 
/*
/*
 * Report the current status of the vc. This is exported to modules (ARub)
 * Report the current status of the vc. This is exported to modules (ARub)
 */
 */
int con_get_info(int *mode, int *shift, int *col, int *row,
int con_get_info(int *mode, int *shift, int *col, int *row,
                        struct tty_struct **tty)
                        struct tty_struct **tty)
{
{
        extern int shift_state;
        extern int shift_state;
 
 
        if (mode) *mode = vtdata.fgconsole->vtd->vc_mode;
        if (mode) *mode = vtdata.fgconsole->vtd->vc_mode;
        if (shift) *shift = shift_state;
        if (shift) *shift = shift_state;
        if (col) *col = vtdata.numcolumns;
        if (col) *col = vtdata.numcolumns;
        if (row) *row = vtdata.numrows;
        if (row) *row = vtdata.numrows;
        if (tty) *tty = *vtdata.fgconsole->tty;
        if (tty) *tty = *vtdata.fgconsole->tty;
        return vtdata.fgconsole->num;
        return vtdata.fgconsole->num;
}
}
 
 

powered by: WebSVN 2.1.0

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