2005-04-17 02:20:36 +04:00
/*
* linux / drivers / video / mdacon . c - - Low level MDA based console driver
*
* ( c ) 1998 Andrew Apted < ajapted @ netspace . net . au >
*
* including portions ( c ) 1995 - 1998 Patrick Caulfield .
*
* slight improvements ( c ) 2000 Edward Betts < edward @ debian . org >
*
* This file is based on the VGA console driver ( vgacon . c ) :
*
* Created 28 Sep 1997 by Geert Uytterhoeven
*
* Rewritten by Martin Mares < mj @ ucw . cz > , July 1998
*
* and on the old console . c , vga . c and vesa_blank . c drivers :
*
* Copyright ( C ) 1991 , 1992 Linus Torvalds
* 1995 Jay Estabrook
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file COPYING in the main directory of this archive for
* more details .
*
* Changelog :
* Paul G . ( 03 / 2001 ) Fix mdacon = boot prompt to use __setup ( ) .
*/
# include <linux/types.h>
# include <linux/fs.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/console.h>
# include <linux/string.h>
# include <linux/kd.h>
# include <linux/vt_kern.h>
# include <linux/vt_buffer.h>
# include <linux/selection.h>
# include <linux/spinlock.h>
# include <linux/ioport.h>
# include <linux/delay.h>
# include <linux/init.h>
# include <asm/io.h>
# include <asm/vga.h>
static DEFINE_SPINLOCK ( mda_lock ) ;
/* description of the hardware layout */
static unsigned long mda_vram_base ; /* Base of video memory */
static unsigned long mda_vram_len ; /* Size of video memory */
static unsigned int mda_num_columns ; /* Number of text columns */
static unsigned int mda_num_lines ; /* Number of text lines */
static unsigned int mda_index_port ; /* Register select port */
static unsigned int mda_value_port ; /* Register value port */
static unsigned int mda_mode_port ; /* Mode control port */
static unsigned int mda_status_port ; /* Status and Config port */
static unsigned int mda_gfx_port ; /* Graphics control port */
/* current hardware state */
static int mda_cursor_loc = - 1 ;
static int mda_cursor_size_from = - 1 ;
static int mda_cursor_size_to = - 1 ;
static enum { TYPE_MDA , TYPE_HERC , TYPE_HERCPLUS , TYPE_HERCCOLOR } mda_type ;
static char * mda_type_name ;
/* console information */
mdacon messing up default vc's - set default to vc13-16 again
mdacon incorrectly detects MDA hardware on systems without such graphics card.
One may load this module by chance, for example when doing some systematical
module-testing, and if there is no Monochrome Display Adapter attached ,
module init renders vc1-16 completely unusable.
I and others have run into this more than once. see [Bug 224522 - modprobe
mdacon freezes machine -> https://bugzilla.novell.com/show_bug.cgi?id=224522 ]
for example
Apparently proper MDA detection seems to be broken for a long time - seems to
be related to those #ifdef TEST_MDA_B statements added by Edward Betts.
this commit back in 2002 made things even worse :
http://git.kernel.org/?p=linux/kernel/git/tglx/history.git;a=commit;h=c72757b49c88914433244757fb4967fc63546685
It changed default vc allocation from 13-16 to 1-16 for no apparent reason
(!?) , and with that (and without X), mdacon grabs the vc you`re currently
sitting on and locks you out.
this is from Kconfig :
>config MDA_CONSOLE
> depends on !M68K && !PARISC && ISA
> tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
> ---help---
> Say Y here if you have an old MDA or monochrome Hercules graphics
> adapter in your system acting as a second head ( = video card). You
> will then be able to use two monitors with your Linux system. Do not
> say Y here if your MDA card is the primary card in your system; the
> normal VGA driver will handle it.
As we can see mdacon is just meant as an additional driver for dual-head
setup, and since kernel 2.4.36 still defaults to vc13-16 , setting the default
back to that value again shouldn`t do any harm.
Hereby i'm reverting that change, setting default back to to vc13-16 again.
Besides the fact that mdacon may be rarely or never be used these days and
could perhaps put to trash anyway (pre-dinosaur hardware!), indeed this is not
a real solution, but at least it removes the unfortunate side-effect of
messing up the vc you`re working on.
Signed-off-by: Roland Kletzing <devzero@web.de>
Cc: James Simmons <jsimmons@infradead.org>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: Tim Schmielau <tim@physik3.uni-rostock.de>
Cc: Jan Engelhardt <jengelh@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-24 08:31:10 +04:00
static int mda_first_vc = 13 ;
2005-04-17 02:20:36 +04:00
static int mda_last_vc = 16 ;
static struct vc_data * mda_display_fg = NULL ;
module_param ( mda_first_vc , int , 0 ) ;
mdacon messing up default vc's - set default to vc13-16 again
mdacon incorrectly detects MDA hardware on systems without such graphics card.
One may load this module by chance, for example when doing some systematical
module-testing, and if there is no Monochrome Display Adapter attached ,
module init renders vc1-16 completely unusable.
I and others have run into this more than once. see [Bug 224522 - modprobe
mdacon freezes machine -> https://bugzilla.novell.com/show_bug.cgi?id=224522 ]
for example
Apparently proper MDA detection seems to be broken for a long time - seems to
be related to those #ifdef TEST_MDA_B statements added by Edward Betts.
this commit back in 2002 made things even worse :
http://git.kernel.org/?p=linux/kernel/git/tglx/history.git;a=commit;h=c72757b49c88914433244757fb4967fc63546685
It changed default vc allocation from 13-16 to 1-16 for no apparent reason
(!?) , and with that (and without X), mdacon grabs the vc you`re currently
sitting on and locks you out.
this is from Kconfig :
>config MDA_CONSOLE
> depends on !M68K && !PARISC && ISA
> tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
> ---help---
> Say Y here if you have an old MDA or monochrome Hercules graphics
> adapter in your system acting as a second head ( = video card). You
> will then be able to use two monitors with your Linux system. Do not
> say Y here if your MDA card is the primary card in your system; the
> normal VGA driver will handle it.
As we can see mdacon is just meant as an additional driver for dual-head
setup, and since kernel 2.4.36 still defaults to vc13-16 , setting the default
back to that value again shouldn`t do any harm.
Hereby i'm reverting that change, setting default back to to vc13-16 again.
Besides the fact that mdacon may be rarely or never be used these days and
could perhaps put to trash anyway (pre-dinosaur hardware!), indeed this is not
a real solution, but at least it removes the unfortunate side-effect of
messing up the vc you`re working on.
Signed-off-by: Roland Kletzing <devzero@web.de>
Cc: James Simmons <jsimmons@infradead.org>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: Tim Schmielau <tim@physik3.uni-rostock.de>
Cc: Jan Engelhardt <jengelh@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-24 08:31:10 +04:00
MODULE_PARM_DESC ( mda_first_vc , " First virtual console. Default: 13 " ) ;
2005-04-17 02:20:36 +04:00
module_param ( mda_last_vc , int , 0 ) ;
mdacon messing up default vc's - set default to vc13-16 again
mdacon incorrectly detects MDA hardware on systems without such graphics card.
One may load this module by chance, for example when doing some systematical
module-testing, and if there is no Monochrome Display Adapter attached ,
module init renders vc1-16 completely unusable.
I and others have run into this more than once. see [Bug 224522 - modprobe
mdacon freezes machine -> https://bugzilla.novell.com/show_bug.cgi?id=224522 ]
for example
Apparently proper MDA detection seems to be broken for a long time - seems to
be related to those #ifdef TEST_MDA_B statements added by Edward Betts.
this commit back in 2002 made things even worse :
http://git.kernel.org/?p=linux/kernel/git/tglx/history.git;a=commit;h=c72757b49c88914433244757fb4967fc63546685
It changed default vc allocation from 13-16 to 1-16 for no apparent reason
(!?) , and with that (and without X), mdacon grabs the vc you`re currently
sitting on and locks you out.
this is from Kconfig :
>config MDA_CONSOLE
> depends on !M68K && !PARISC && ISA
> tristate "MDA text console (dual-headed) (EXPERIMENTAL)"
> ---help---
> Say Y here if you have an old MDA or monochrome Hercules graphics
> adapter in your system acting as a second head ( = video card). You
> will then be able to use two monitors with your Linux system. Do not
> say Y here if your MDA card is the primary card in your system; the
> normal VGA driver will handle it.
As we can see mdacon is just meant as an additional driver for dual-head
setup, and since kernel 2.4.36 still defaults to vc13-16 , setting the default
back to that value again shouldn`t do any harm.
Hereby i'm reverting that change, setting default back to to vc13-16 again.
Besides the fact that mdacon may be rarely or never be used these days and
could perhaps put to trash anyway (pre-dinosaur hardware!), indeed this is not
a real solution, but at least it removes the unfortunate side-effect of
messing up the vc you`re working on.
Signed-off-by: Roland Kletzing <devzero@web.de>
Cc: James Simmons <jsimmons@infradead.org>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: Tim Schmielau <tim@physik3.uni-rostock.de>
Cc: Jan Engelhardt <jengelh@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-24 08:31:10 +04:00
MODULE_PARM_DESC ( mda_last_vc , " Last virtual console. Default: 16 " ) ;
2005-04-17 02:20:36 +04:00
/* MDA register values
*/
# define MDA_CURSOR_BLINKING 0x00
# define MDA_CURSOR_OFF 0x20
# define MDA_CURSOR_SLOWBLINK 0x60
# define MDA_MODE_GRAPHICS 0x02
# define MDA_MODE_VIDEO_EN 0x08
# define MDA_MODE_BLINK_EN 0x20
# define MDA_MODE_GFX_PAGE1 0x80
# define MDA_STATUS_HSYNC 0x01
# define MDA_STATUS_VSYNC 0x80
# define MDA_STATUS_VIDEO 0x08
# define MDA_CONFIG_COL132 0x08
# define MDA_GFX_MODE_EN 0x01
# define MDA_GFX_PAGE_EN 0x02
/*
* MDA could easily be classified as " pre-dinosaur hardware " .
*/
static void write_mda_b ( unsigned int val , unsigned char reg )
{
unsigned long flags ;
spin_lock_irqsave ( & mda_lock , flags ) ;
outb_p ( reg , mda_index_port ) ;
outb_p ( val , mda_value_port ) ;
spin_unlock_irqrestore ( & mda_lock , flags ) ;
}
static void write_mda_w ( unsigned int val , unsigned char reg )
{
unsigned long flags ;
spin_lock_irqsave ( & mda_lock , flags ) ;
outb_p ( reg , mda_index_port ) ; outb_p ( val > > 8 , mda_value_port ) ;
outb_p ( reg + 1 , mda_index_port ) ; outb_p ( val & 0xff , mda_value_port ) ;
spin_unlock_irqrestore ( & mda_lock , flags ) ;
}
# ifdef TEST_MDA_B
static int test_mda_b ( unsigned char val , unsigned char reg )
{
unsigned long flags ;
spin_lock_irqsave ( & mda_lock , flags ) ;
outb_p ( reg , mda_index_port ) ;
outb ( val , mda_value_port ) ;
udelay ( 20 ) ; val = ( inb_p ( mda_value_port ) = = val ) ;
spin_unlock_irqrestore ( & mda_lock , flags ) ;
return val ;
}
# endif
static inline void mda_set_cursor ( unsigned int location )
{
if ( mda_cursor_loc = = location )
return ;
write_mda_w ( location > > 1 , 0x0e ) ;
mda_cursor_loc = location ;
}
static inline void mda_set_cursor_size ( int from , int to )
{
if ( mda_cursor_size_from = = from & & mda_cursor_size_to = = to )
return ;
if ( from > to ) {
write_mda_b ( MDA_CURSOR_OFF , 0x0a ) ; /* disable cursor */
} else {
write_mda_b ( from , 0x0a ) ; /* cursor start */
write_mda_b ( to , 0x0b ) ; /* cursor end */
}
mda_cursor_size_from = from ;
mda_cursor_size_to = to ;
}
# ifndef MODULE
static int __init mdacon_setup ( char * str )
{
/* command line format: mdacon=<first>,<last> */
int ints [ 3 ] ;
str = get_options ( str , ARRAY_SIZE ( ints ) , ints ) ;
if ( ints [ 0 ] < 2 )
return 0 ;
if ( ints [ 1 ] < 1 | | ints [ 1 ] > MAX_NR_CONSOLES | |
ints [ 2 ] < 1 | | ints [ 2 ] > MAX_NR_CONSOLES )
return 0 ;
mda_first_vc = ints [ 1 ] ;
mda_last_vc = ints [ 2 ] ;
return 1 ;
}
__setup ( " mdacon= " , mdacon_setup ) ;
# endif
2006-07-30 14:03:46 +04:00
static int mda_detect ( void )
2005-04-17 02:20:36 +04:00
{
int count = 0 ;
u16 * p , p_save ;
u16 * q , q_save ;
/* do a memory check */
p = ( u16 * ) mda_vram_base ;
q = ( u16 * ) ( mda_vram_base + 0x01000 ) ;
p_save = scr_readw ( p ) ; q_save = scr_readw ( q ) ;
scr_writew ( 0xAA55 , p ) ; if ( scr_readw ( p ) = = 0xAA55 ) count + + ;
scr_writew ( 0x55AA , p ) ; if ( scr_readw ( p ) = = 0x55AA ) count + + ;
scr_writew ( p_save , p ) ;
if ( count ! = 2 ) {
return 0 ;
}
/* check if we have 4K or 8K */
scr_writew ( 0xA55A , q ) ; scr_writew ( 0x0000 , p ) ;
if ( scr_readw ( q ) = = 0xA55A ) count + + ;
scr_writew ( 0x5AA5 , q ) ; scr_writew ( 0x0000 , p ) ;
if ( scr_readw ( q ) = = 0x5AA5 ) count + + ;
scr_writew ( p_save , p ) ; scr_writew ( q_save , q ) ;
if ( count = = 4 ) {
mda_vram_len = 0x02000 ;
}
/* Ok, there is definitely a card registering at the correct
* memory location , so now we do an I / O port test .
*/
# ifdef TEST_MDA_B
/* Edward: These two mess `tests' mess up my cursor on bootup */
/* cursor low register */
if ( ! test_mda_b ( 0x66 , 0x0f ) ) {
return 0 ;
}
/* cursor low register */
if ( ! test_mda_b ( 0x99 , 0x0f ) ) {
return 0 ;
}
# endif
/* See if the card is a Hercules, by checking whether the vsync
* bit of the status register is changing . This test lasts for
* approximately 1 / 10 th of a second .
*/
p_save = q_save = inb_p ( mda_status_port ) & MDA_STATUS_VSYNC ;
for ( count = 0 ; count < 50000 & & p_save = = q_save ; count + + ) {
q_save = inb ( mda_status_port ) & MDA_STATUS_VSYNC ;
udelay ( 2 ) ;
}
if ( p_save ! = q_save ) {
switch ( inb_p ( mda_status_port ) & 0x70 ) {
case 0x10 :
mda_type = TYPE_HERCPLUS ;
mda_type_name = " HerculesPlus " ;
break ;
case 0x50 :
mda_type = TYPE_HERCCOLOR ;
mda_type_name = " HerculesColor " ;
break ;
default :
mda_type = TYPE_HERC ;
mda_type_name = " Hercules " ;
break ;
}
}
return 1 ;
}
2006-07-30 14:03:46 +04:00
static void mda_initialize ( void )
2005-04-17 02:20:36 +04:00
{
write_mda_b ( 97 , 0x00 ) ; /* horizontal total */
write_mda_b ( 80 , 0x01 ) ; /* horizontal displayed */
write_mda_b ( 82 , 0x02 ) ; /* horizontal sync pos */
write_mda_b ( 15 , 0x03 ) ; /* horizontal sync width */
write_mda_b ( 25 , 0x04 ) ; /* vertical total */
write_mda_b ( 6 , 0x05 ) ; /* vertical total adjust */
write_mda_b ( 25 , 0x06 ) ; /* vertical displayed */
write_mda_b ( 25 , 0x07 ) ; /* vertical sync pos */
write_mda_b ( 2 , 0x08 ) ; /* interlace mode */
write_mda_b ( 13 , 0x09 ) ; /* maximum scanline */
write_mda_b ( 12 , 0x0a ) ; /* cursor start */
write_mda_b ( 13 , 0x0b ) ; /* cursor end */
write_mda_w ( 0x0000 , 0x0c ) ; /* start address */
write_mda_w ( 0x0000 , 0x0e ) ; /* cursor location */
outb_p ( MDA_MODE_VIDEO_EN | MDA_MODE_BLINK_EN , mda_mode_port ) ;
outb_p ( 0x00 , mda_status_port ) ;
outb_p ( 0x00 , mda_gfx_port ) ;
}
2006-06-26 11:27:15 +04:00
static const char * mdacon_startup ( void )
2005-04-17 02:20:36 +04:00
{
mda_num_columns = 80 ;
mda_num_lines = 25 ;
mda_vram_len = 0x01000 ;
[PATCH] vgacon: make VGA_MAP_MEM take size, remove extra use
VGA_MAP_MEM translates to ioremap() on some architectures. It makes sense
to do this to vga_vram_base, because we're going to access memory between
vga_vram_base and vga_vram_end.
But it doesn't really make sense to map starting at vga_vram_end, because
we aren't going to access memory starting there. On ia64, which always has
to be different, ioremapping vga_vram_end gives you something completely
incompatible with ioremapped vga_vram_start, so vga_vram_size ends up being
nonsense.
As a bonus, we often know the size up front, so we can use ioremap()
correctly, rather than giving it a zero size.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: "Luck, Tony" <tony.luck@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-06-23 01:47:32 +04:00
mda_vram_base = VGA_MAP_MEM ( 0xb0000 , mda_vram_len ) ;
2005-04-17 02:20:36 +04:00
mda_index_port = 0x3b4 ;
mda_value_port = 0x3b5 ;
mda_mode_port = 0x3b8 ;
mda_status_port = 0x3ba ;
mda_gfx_port = 0x3bf ;
mda_type = TYPE_MDA ;
mda_type_name = " MDA " ;
if ( ! mda_detect ( ) ) {
printk ( " mdacon: MDA card not detected. \n " ) ;
return NULL ;
}
if ( mda_type ! = TYPE_MDA ) {
mda_initialize ( ) ;
}
/* cursor looks ugly during boot-up, so turn it off */
mda_set_cursor ( mda_vram_len - 1 ) ;
printk ( " mdacon: %s with %ldK of memory detected. \n " ,
mda_type_name , mda_vram_len / 1024 ) ;
return " MDA-2 " ;
}
static void mdacon_init ( struct vc_data * c , int init )
{
c - > vc_complement_mask = 0x0800 ; /* reverse video */
c - > vc_display_fg = & mda_display_fg ;
if ( init ) {
c - > vc_cols = mda_num_columns ;
c - > vc_rows = mda_num_lines ;
} else
vc_resize ( c , mda_num_columns , mda_num_lines ) ;
/* make the first MDA console visible */
if ( mda_display_fg = = NULL )
mda_display_fg = c ;
}
static void mdacon_deinit ( struct vc_data * c )
{
/* con_set_default_unimap(c->vc_num); */
if ( mda_display_fg = = c )
mda_display_fg = NULL ;
}
static inline u16 mda_convert_attr ( u16 ch )
{
u16 attr = 0x0700 ;
/* Underline and reverse-video are mutually exclusive on MDA.
* Since reverse - video is used for cursors and selected areas ,
* it takes precedence .
*/
if ( ch & 0x0800 ) attr = 0x7000 ; /* reverse */
else if ( ch & 0x0400 ) attr = 0x0100 ; /* underline */
return ( ( ch & 0x0200 ) < < 2 ) | /* intensity */
( ch & 0x8000 ) | /* blink */
( ch & 0x00ff ) | attr ;
}
static u8 mdacon_build_attr ( struct vc_data * c , u8 color , u8 intensity ,
2007-05-08 11:38:04 +04:00
u8 blink , u8 underline , u8 reverse , u8 italic )
2005-04-17 02:20:36 +04:00
{
/* The attribute is just a bit vector:
*
* Bit 0. .1 : intensity ( 0. .2 )
* Bit 2 : underline
* Bit 3 : reverse
* Bit 7 : blink
*/
return ( intensity & 3 ) |
( ( underline & 1 ) < < 2 ) |
( ( reverse & 1 ) < < 3 ) |
2007-05-08 11:38:04 +04:00
( ! ! italic < < 4 ) |
2005-04-17 02:20:36 +04:00
( ( blink & 1 ) < < 7 ) ;
}
static void mdacon_invert_region ( struct vc_data * c , u16 * p , int count )
{
for ( ; count > 0 ; count - - ) {
scr_writew ( scr_readw ( p ) ^ 0x0800 , p ) ;
p + + ;
}
}
# define MDA_ADDR(x,y) ((u16 *) mda_vram_base + (y)*mda_num_columns + (x))
static void mdacon_putc ( struct vc_data * c , int ch , int y , int x )
{
scr_writew ( mda_convert_attr ( ch ) , MDA_ADDR ( x , y ) ) ;
}
static void mdacon_putcs ( struct vc_data * c , const unsigned short * s ,
int count , int y , int x )
{
u16 * dest = MDA_ADDR ( x , y ) ;
for ( ; count > 0 ; count - - ) {
scr_writew ( mda_convert_attr ( scr_readw ( s + + ) ) , dest + + ) ;
}
}
static void mdacon_clear ( struct vc_data * c , int y , int x ,
int height , int width )
{
u16 * dest = MDA_ADDR ( x , y ) ;
u16 eattr = mda_convert_attr ( c - > vc_video_erase_char ) ;
if ( width < = 0 | | height < = 0 )
return ;
if ( x = = 0 & & width = = mda_num_columns ) {
scr_memsetw ( dest , eattr , height * width * 2 ) ;
} else {
for ( ; height > 0 ; height - - , dest + = mda_num_columns )
scr_memsetw ( dest , eattr , width * 2 ) ;
}
}
static void mdacon_bmove ( struct vc_data * c , int sy , int sx ,
int dy , int dx , int height , int width )
{
u16 * src , * dest ;
if ( width < = 0 | | height < = 0 )
return ;
if ( sx = = 0 & & dx = = 0 & & width = = mda_num_columns ) {
scr_memmovew ( MDA_ADDR ( 0 , dy ) , MDA_ADDR ( 0 , sy ) , height * width * 2 ) ;
} else if ( dy < sy | | ( dy = = sy & & dx < sx ) ) {
src = MDA_ADDR ( sx , sy ) ;
dest = MDA_ADDR ( dx , dy ) ;
for ( ; height > 0 ; height - - ) {
scr_memmovew ( dest , src , width * 2 ) ;
src + = mda_num_columns ;
dest + = mda_num_columns ;
}
} else {
src = MDA_ADDR ( sx , sy + height - 1 ) ;
dest = MDA_ADDR ( dx , dy + height - 1 ) ;
for ( ; height > 0 ; height - - ) {
scr_memmovew ( dest , src , width * 2 ) ;
src - = mda_num_columns ;
dest - = mda_num_columns ;
}
}
}
static int mdacon_switch ( struct vc_data * c )
{
return 1 ; /* redrawing needed */
}
static int mdacon_set_palette ( struct vc_data * c , unsigned char * table )
{
return - EINVAL ;
}
static int mdacon_blank ( struct vc_data * c , int blank , int mode_switch )
{
if ( mda_type = = TYPE_MDA ) {
if ( blank )
scr_memsetw ( ( void * ) mda_vram_base ,
mda_convert_attr ( c - > vc_video_erase_char ) ,
c - > vc_screenbuf_size ) ;
/* Tell console.c that it has to restore the screen itself */
return 1 ;
} else {
if ( blank )
outb_p ( 0x00 , mda_mode_port ) ; /* disable video */
else
outb_p ( MDA_MODE_VIDEO_EN | MDA_MODE_BLINK_EN ,
mda_mode_port ) ;
return 0 ;
}
}
static int mdacon_scrolldelta ( struct vc_data * c , int lines )
{
return 0 ;
}
static void mdacon_cursor ( struct vc_data * c , int mode )
{
if ( mode = = CM_ERASE ) {
mda_set_cursor ( mda_vram_len - 1 ) ;
return ;
}
mda_set_cursor ( c - > vc_y * mda_num_columns * 2 + c - > vc_x * 2 ) ;
switch ( c - > vc_cursor_type & 0x0f ) {
case CUR_LOWER_THIRD : mda_set_cursor_size ( 10 , 13 ) ; break ;
case CUR_LOWER_HALF : mda_set_cursor_size ( 7 , 13 ) ; break ;
case CUR_TWO_THIRDS : mda_set_cursor_size ( 4 , 13 ) ; break ;
case CUR_BLOCK : mda_set_cursor_size ( 1 , 13 ) ; break ;
case CUR_NONE : mda_set_cursor_size ( 14 , 13 ) ; break ;
default : mda_set_cursor_size ( 12 , 13 ) ; break ;
}
}
static int mdacon_scroll ( struct vc_data * c , int t , int b , int dir , int lines )
{
2008-10-14 23:12:02 +04:00
u16 eattr = mda_convert_attr ( c - > vc_video_erase_char ) ;
2005-04-17 02:20:36 +04:00
if ( ! lines )
return 0 ;
if ( lines > c - > vc_rows ) /* maximum realistic size */
lines = c - > vc_rows ;
switch ( dir ) {
case SM_UP :
scr_memmovew ( MDA_ADDR ( 0 , t ) , MDA_ADDR ( 0 , t + lines ) ,
( b - t - lines ) * mda_num_columns * 2 ) ;
scr_memsetw ( MDA_ADDR ( 0 , b - lines ) , eattr ,
lines * mda_num_columns * 2 ) ;
break ;
case SM_DOWN :
scr_memmovew ( MDA_ADDR ( 0 , t + lines ) , MDA_ADDR ( 0 , t ) ,
( b - t - lines ) * mda_num_columns * 2 ) ;
scr_memsetw ( MDA_ADDR ( 0 , t ) , eattr , lines * mda_num_columns * 2 ) ;
break ;
}
return 0 ;
}
/*
* The console ` switch ' structure for the MDA based console
*/
static const struct consw mda_con = {
. owner = THIS_MODULE ,
. con_startup = mdacon_startup ,
. con_init = mdacon_init ,
. con_deinit = mdacon_deinit ,
. con_clear = mdacon_clear ,
. con_putc = mdacon_putc ,
. con_putcs = mdacon_putcs ,
. con_cursor = mdacon_cursor ,
. con_scroll = mdacon_scroll ,
. con_bmove = mdacon_bmove ,
. con_switch = mdacon_switch ,
. con_blank = mdacon_blank ,
. con_set_palette = mdacon_set_palette ,
. con_scrolldelta = mdacon_scrolldelta ,
. con_build_attr = mdacon_build_attr ,
. con_invert_region = mdacon_invert_region ,
} ;
int __init mda_console_init ( void )
{
if ( mda_first_vc > mda_last_vc )
return 1 ;
return take_over_console ( & mda_con , mda_first_vc - 1 , mda_last_vc - 1 , 0 ) ;
}
static void __exit mda_console_exit ( void )
{
give_up_console ( & mda_con ) ;
}
module_init ( mda_console_init ) ;
module_exit ( mda_console_exit ) ;
MODULE_LICENSE ( " GPL " ) ;