]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/console/i386/text_console.c
xnu-517.tar.gz
[apple/xnu.git] / osfmk / console / i386 / text_console.c
diff --git a/osfmk/console/i386/text_console.c b/osfmk/console/i386/text_console.c
new file mode 100644 (file)
index 0000000..37154d4
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * text_console.c
+ *
+ * VGA text console support.
+ */
+
+#include <i386/pio.h>
+#include <console/video_console.h>
+
+/*
+ * Macros and typedefs.
+ */
+typedef short  csrpos_t;    /* cursor position, ONE_SPACE bytes per char */
+
+#define ONE_SPACE       2                       /* bytes per character */
+#define ONE_LINE        (vga_cols * ONE_SPACE)  /* number of bytes in line */
+#define ONE_PAGE        (vga_rows * ONE_LINE)   /* number of bytes in page */
+#define SPACE_CHAR      0x20
+
+#define VGA_FB_START    0x0b8000
+#define VGA_FB_SIZE     0x8000
+#define VGA_IDX_REG     0x3d4
+#define VGA_IO_REG      0x3d5
+
+/*
+ * Commands sent to graphics adapter.
+ */
+#define VGA_C_LOW           0x0f    /* return low byte of cursor addr */
+#define VGA_C_HIGH          0x0e    /* high byte */
+
+/*
+ * Attributes for character sent to display.
+ */
+#define VGA_ATTR_NORMAL     0x07
+#define VGA_ATTR_REVERSE    0x70
+
+/*
+ * Convert from XY coordinate to a location in display memory.
+ */
+#define XY_TO_CSRPOS(x, y)    (((y) * vga_cols + (x)) * ONE_SPACE)
+
+/*
+ * Globals.
+ */
+static short    vga_idx_reg     = 0;   /* location of VGA index register */
+static short    vga_io_reg      = 0;   /* location of VGA data register */
+static short    vga_cols        = 80;  /* number of columns */
+static short    vga_rows        = 25;  /* number of rows */
+static char     vga_attr        = 0;   /* current character attribute */
+static char     vga_attr_rev    = 0;   /* current reverse attribute */
+static char *   vram_start      = 0;   /* VM start of VGA frame buffer */
+
+/*
+ * Functions in kdasm.s.
+ */
+extern void kd_slmwd(unsigned char * pos, int count, unsigned short val);
+extern void kd_slmscu(unsigned char * from, unsigned char * to, int count);
+extern void kd_slmscd(unsigned char * from, unsigned char * to, int count);
+
+/*
+ * move_up
+ *
+ * Block move up for VGA.
+ */
+static void
+move_up( csrpos_t  from,
+         csrpos_t  to,
+         int       count)
+{
+    kd_slmscu( vram_start + from, vram_start + to, count );
+}
+
+/*
+ * move_down
+ *
+ * Block move down for VGA.
+ */
+static void
+move_down( csrpos_t  from,
+           csrpos_t  to,
+           int       count )
+{
+    kd_slmscd( vram_start + from, vram_start + to, count );
+}
+
+/*
+ * clear_block
+ *
+ * Fast clear for VGA.
+ */
+static void
+clear_block( csrpos_t  start,
+             int       size,
+             char      attr)
+{
+    kd_slmwd( vram_start + start, size,
+              ((unsigned short) attr << 8) + SPACE_CHAR);
+}
+
+/*
+ * set_cursor_position
+ *
+ * This function sets the hardware cursor position
+ * on the screen.
+ */
+static void
+set_cursor_position( csrpos_t newpos )
+{
+    short curpos;  /* position, not scaled for attribute byte */
+
+    curpos = newpos / ONE_SPACE;
+
+    outb(vga_idx_reg, VGA_C_HIGH);
+    outb(vga_io_reg, (unsigned char)(curpos >> 8));
+
+    outb(vga_idx_reg, VGA_C_LOW);
+    outb(vga_io_reg, (unsigned char)(curpos & 0xff));
+}
+
+/*
+ * display_char
+ *
+ * Display attributed character for VGA (mode 3).
+ */
+static void
+display_char( csrpos_t    pos,      /* where to put it */
+              char        ch,       /* the character */
+              char        attr )    /* its attribute */
+{
+    *(vram_start + pos)     = ch;
+    *(vram_start + pos + 1) = attr;
+}
+
+/*
+ * vga_init
+ *
+ * Initialize the VGA text console.
+ */
+static void
+vga_init(int cols, int rows, unsigned char * addr)
+{
+    vram_start   = addr;
+    vga_idx_reg  = VGA_IDX_REG;
+    vga_io_reg   = VGA_IO_REG;
+    vga_rows     = rows;
+    vga_cols     = cols;
+    vga_attr     = VGA_ATTR_NORMAL;
+    vga_attr_rev = VGA_ATTR_REVERSE;
+
+    set_cursor_position(0);
+}
+
+/*
+ * tc_scroll_up
+ *
+ * Scroll the screen up 'n' character lines.
+ */
+void
+tc_scroll_up( int lines, int top, int bottom )
+{
+    csrpos_t  to;
+    csrpos_t  from;
+    int       size;
+
+    /* scroll up */
+    to   = 0;
+    from = ONE_LINE * lines;
+    size = ( ONE_PAGE - ( ONE_LINE * lines ) ) / ONE_SPACE;
+    move_up(from, to, size);
+
+    /* clear bottom line */
+    to   = ( ( vga_rows - lines) * ONE_LINE );
+    size = ( ONE_LINE * lines ) / ONE_SPACE;
+    clear_block(to, size, vga_attr);
+}
+
+/*
+ * tc_scroll_down
+ *
+ * Scrolls the screen down 'n' character lines.
+ */
+void
+tc_scroll_down( int lines, int top, int bottom )
+{
+    csrpos_t  to;
+    csrpos_t  from;
+    int       size;
+
+    /* move down */
+    to   = ONE_PAGE - ONE_SPACE;
+    from = ONE_PAGE - ( ONE_LINE * lines ) - ONE_SPACE;
+    size = ( ONE_PAGE - ( ONE_LINE * lines ) ) / ONE_SPACE;
+    move_down(from, to, size);
+
+    /* clear top line */
+    to   = 0;
+    size = ( ONE_LINE * lines ) / ONE_SPACE;
+    clear_block(to, size, vga_attr);
+}
+
+/* Default colors for 16-color palette */
+enum {
+    kVGAColorBlack = 0,
+    kVGAColorBlue,
+    kVGAColorGreen,
+    kVGAColorCyan,
+    kVGAColorRed,
+    kVGAColorMagenta,
+    kVGAColorBrown,
+    kVGAColorWhite,
+    kVGAColorGray,
+    kVGAColorLightBlue,
+    kVGAColorLightGreen,
+    kVGAColorLightCyan,
+    kVGAColorLightRed,
+    kVGAColorLightMagenta,
+    kVGAColorLightBrown,
+    kVGAColorBrightWhite
+};
+
+/*
+ * tc_update_color
+ *
+ * Update the foreground / background color.
+ */
+void
+tc_update_color( int color, int fore )
+{
+    unsigned char mask_on, mask_off;
+
+    switch ( color )
+    {
+        case 1:  mask_on = kVGAColorRed;        break;
+        case 3:  mask_on = kVGAColorLightBrown; break;
+        case 4:  mask_on = kVGAColorBlue;       break;
+        case 6:  mask_on = kVGAColorCyan;       break;
+        default: mask_on = color;               break;
+    }
+
+    if ( fore )
+    {
+        mask_off = 0x0f;
+    }
+    else
+    {
+        mask_off = 0xf0;
+        mask_on  <<= 4;
+    }
+
+    vga_attr     = (vga_attr & ~mask_off) | mask_on;
+
+    vga_attr_rev = ( ((vga_attr << 4) & 0xf0) |
+                     ((vga_attr >> 4) & 0x0f) );
+}
+
+/*
+ * tc_show_cursor
+ *
+ * Show the hardware cursor.
+ */
+void
+tc_show_cursor( int x, int y )
+{
+    set_cursor_position( XY_TO_CSRPOS(x, y) );
+}
+
+/*
+ * tc_hide_cursor
+ *
+ * Hide the hardware cursor.
+ */
+void
+tc_hide_cursor( int x, int y )
+{
+    return;
+}
+
+/*
+ * tc_clear_screen
+ *
+ * Clear the entire screen, or a portion of the screen
+ * relative to the current cursor position.
+ */
+void
+tc_clear_screen(int x, int y, int top, int bottom, int operation)
+{
+    csrpos_t start;
+    int      count;
+
+    switch ( operation )
+    {
+        case 0:   /* To end of screen */
+            start = XY_TO_CSRPOS(x, y);
+            count = ONE_PAGE - start;
+            break;
+        case 1:   /* To start of screen */
+            start = 0;
+            count = XY_TO_CSRPOS(x, y) + ONE_SPACE;
+            break;
+        default:
+        case 2:   /* Whole screen */
+            start = 0;
+            count = ONE_PAGE;
+            break;
+    }
+    clear_block(start, count, vga_attr);
+}
+
+/*
+ * tc_paint_char
+ *
+ * Display a character on screen with the given coordinates,
+ * and attributes.
+ */
+void
+tc_paint_char( int x, int y, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous )
+{
+    char my_attr = vga_attr;
+
+    if ( attrs & 4 ) my_attr = vga_attr_rev;
+
+    display_char( XY_TO_CSRPOS(x, y), ch, vga_attr );
+}
+
+/*
+ * tc_enable
+ *
+ * Enable / disable the console.
+ */
+void
+tc_enable(boolean_t enable)
+{
+
+}
+
+/*
+ * tc_initialize
+ *
+ * Must be called before any other exported functions.
+ */
+void
+tc_initialize(struct vc_info * vinfo_p)
+{
+    vinfo_p->v_rows    = vinfo_p->v_height;
+    vinfo_p->v_columns = vinfo_p->v_width;
+
+    vga_init( vinfo_p->v_columns,
+              vinfo_p->v_rows,
+              (unsigned char *) vinfo_p->v_baseaddr);
+}