You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
882 lines
25 KiB
882 lines
25 KiB
3 weeks ago
|
/* vxbM6845Vga.c - motorola 6845 VGA console driver */
|
||
|
|
||
|
/*
|
||
|
* Copyright (c) 2007, 2008, 2010, 2012, 2013 Wind River Systems, Inc.
|
||
|
*
|
||
|
* The right to copy, distribute, modify or otherwise make use
|
||
|
* of this software may be licensed only pursuant to the terms
|
||
|
* of an applicable Wind River license agreement.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
modification history
|
||
|
--------------------
|
||
|
01p,21may13,y_y initialized the paramter escFlags. (WIND00416649)
|
||
|
01o,17aug12,clx Removed unnecessary import function declare. (WIND00365597)
|
||
|
01n,02feb12,sye Removed redundant auto wrapped blank line. (WIND00311642)
|
||
|
01m,06sep10,jxu Replace inclusion of funcBindP.h with selectLibP.h
|
||
|
01l,03may10,h_k cleaned up a compiler warning.
|
||
|
01k,07jan10,jc0 LP64 adaptation.
|
||
|
01j,12dec08,h_k added more information in the API reference manual.
|
||
|
01i,27aug08,jpb Renamed VSB header file
|
||
|
01h,18jun08,jpb Renamed _WRS_VX_SMP to _WRS_CONFIG_SMP. Added include path
|
||
|
for kernel configurations options set in vsb.
|
||
|
01g,16jun08,pmr resource documentation
|
||
|
01f,05may08,tor update version
|
||
|
01e,06mar08,tor resource meta-data update
|
||
|
01d,20sep07,tor VXB_VERSION_3
|
||
|
01c,17aug07,pmr new register access methods
|
||
|
01b,09mar07,pmr SMP-safe.
|
||
|
01a,20feb07,pmr adapted for VxBus from version 01e.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
DESCRIPTION
|
||
|
This is the driver fo Video Contoroller Chip (6845) normally used in the
|
||
|
386/486 personal computers.
|
||
|
|
||
|
USER CALLABLE ROUTINES
|
||
|
This driver provides several VxBus methods for external access to its
|
||
|
routines.
|
||
|
|
||
|
All virtual consoles are mapped to the same screen buffer. This is a
|
||
|
very basic implementation of virtual consoles. Multiple screen
|
||
|
buffers are not used to switch between consoles. This implementation
|
||
|
is left for the future. Mutual exclusion for the screen buffer is
|
||
|
guaranteed within the same console but it is not implemented across multiple
|
||
|
virtual consoles because all virtual consoles use the same screen buffer. If
|
||
|
multiple screen buffers are implemented then the mutual exclusion between
|
||
|
virtual consoles can be implemented.
|
||
|
This driver suports the ansi escape sequences and special processing in the
|
||
|
m6845 driver will be done if an escape sequence exists.
|
||
|
If the ansi escape sequences are not required, please rebuild this driver
|
||
|
without defining INCLUDE_ANSI_ESC_SEQUENCE macro, which is explicitly defined
|
||
|
in this file.
|
||
|
|
||
|
TARGET-SPECIFIC PARAMETERS
|
||
|
|
||
|
The parameters are provided through `m6845Vga' registration defined in
|
||
|
hwconf.c in the target BSP.
|
||
|
|
||
|
\is
|
||
|
\i <regBase>
|
||
|
The Video Contoroller Chip register base address.
|
||
|
The parameter type is HCF_RES_INT, or HCF_RES_ADDR for 64-bit address in LP64.
|
||
|
If not specified, 0 will be set in the register base address and VXB_REG_NONE
|
||
|
will be set in the register base flag that will cause a failure at vxbRegMap()
|
||
|
to obtain the access handle.
|
||
|
|
||
|
\i <regBase1>
|
||
|
The address of video memory.
|
||
|
If not specified, the address passed by <memBase> will be set as the video
|
||
|
memory address.
|
||
|
The parameter type is HCF_RES_INT, or HCF_RES_ADDR for 64-bit address in LP64.
|
||
|
|
||
|
\i <memBase>
|
||
|
The address of video memory (for backward compatibility).
|
||
|
If not specified here nor in <regBase1>, 0 will be set as the video memory
|
||
|
address.
|
||
|
The parameter type is HCF_RES_INT, or HCF_RES_ADDR for 64-bit address in LP64.
|
||
|
|
||
|
\i <colorMode>
|
||
|
Specify color mode, COLOR(1) or MONO(0).
|
||
|
If not specified, MONO(0) will be set as the color mode.
|
||
|
The parameter type is HCF_RES_INT.
|
||
|
|
||
|
\i <colorSetting>
|
||
|
Specify the foreground and background display colors.
|
||
|
If not specifed, (ATRB_FG_BRIGHTWHITE | ATRB_BG_BROWN) will be set when the
|
||
|
<colorMode> is COLOR(1) and (ATRB_FG_WHITE | ATRB_BG_BLACK) will be set when
|
||
|
the <colorMode> is MONO(0) for the display attributes.
|
||
|
The parameter type is HCF_RES_INT.
|
||
|
|
||
|
\ie
|
||
|
|
||
|
By convention all the BSP-specific device parameters are registered in
|
||
|
a file called hwconf.c, which is #include'ed by sysLib.c.
|
||
|
The following is an example in pcPentium4 BSP:
|
||
|
|
||
|
\cs
|
||
|
LOCAL const struct hcfResource pentiumM6845VgaResources[] =
|
||
|
{
|
||
|
{ "regBase", HCF_RES_ADDR, {(void *) CTRL_SEL_REG} },
|
||
|
{ "regBase1", HCF_RES_ADDR, {(void *) CTRL_MEM_BASE} },
|
||
|
{ "colorMode", HCF_RES_INT, {(void *) COLOR_MODE} },
|
||
|
{ "colorSetting",HCF_RES_INT, {(void *) DEFAULT_ATR} },
|
||
|
};
|
||
|
#define pentiumM6845VgaNum NELEMENTS(pentiumM6845VgaResources)
|
||
|
|
||
|
|
||
|
const struct hcfDevice hcfDeviceList[] = {
|
||
|
|
||
|
...
|
||
|
|
||
|
|
||
|
{ "m6845Vga", 0, VXB_BUSID_PLB, 0, pentiumM6845VgaNum,
|
||
|
pentiumM6845VgaResources },
|
||
|
|
||
|
...
|
||
|
|
||
|
};
|
||
|
\ce
|
||
|
|
||
|
CONFIGURATION
|
||
|
To use the driver, configure VxWorks with the
|
||
|
DRV_VGA_M6845 component.
|
||
|
The required components for this driver are
|
||
|
INCLUDE_VXBUS
|
||
|
INCLUDE_PLB_BUS
|
||
|
INCLUDE_PC_CONSOLE
|
||
|
which will be dragged by Kernel Configuration tool if not included in the
|
||
|
VxWorks Image Project (VIP) when the DRV_VGA_M6845 is added.
|
||
|
You need to define all the required components when the DRV_VGA_M6845
|
||
|
is added in config.h for BSP build unless they are already defined.
|
||
|
|
||
|
NOTES
|
||
|
The macro N_VIRTUAL_CONSOLES should be defined in config.h file.
|
||
|
This refers to the number of virtual consoles which the user wishes to have.
|
||
|
|
||
|
SEE ALSO: tyLib, vxbPcConsole and VxWorks Device Driver Developer's Guide.
|
||
|
|
||
|
*/
|
||
|
|
||
|
/* includes */
|
||
|
|
||
|
#include <vxWorks.h>
|
||
|
#include <vsbConfig.h>
|
||
|
#include <iv.h>
|
||
|
#include <ioLib.h>
|
||
|
#include <iosLib.h>
|
||
|
#include <memLib.h>
|
||
|
#include <private/funcBindP.h>
|
||
|
#include <intLib.h>
|
||
|
#include <taskLib.h>
|
||
|
#include <errnoLib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include "font_8x16.h"
|
||
|
#include <private/funcBindP.h>
|
||
|
#include <private/selectLibP.h> /* _func_selWakeupAll */
|
||
|
|
||
|
/* SMP */
|
||
|
|
||
|
#ifdef _WRS_CONFIG_SMP
|
||
|
#include <spinLockLib.h>
|
||
|
#define M6845_LOCK_TAKE(p) \
|
||
|
if (INT_CONTEXT()) \
|
||
|
SPIN_LOCK_ISR_TAKE(&p->pTyDev->spinlockIsr)
|
||
|
|
||
|
#define M6845_LOCK_GIVE(p) \
|
||
|
if (INT_CONTEXT()) \
|
||
|
SPIN_LOCK_ISR_GIVE(&p->pTyDev->spinlockIsr)
|
||
|
#else /* _WRS_CONFIG_SMP */
|
||
|
#define M6845_LOCK_TAKE(p)
|
||
|
#define M6845_LOCK_GIVE(p)
|
||
|
#endif /* _WRS_CONFIG_SMP */
|
||
|
#define DEFAULT_FB_MEM 0x00000000
|
||
|
|
||
|
/* VXBUS */
|
||
|
|
||
|
#include <vxBusLib.h>
|
||
|
#include <hwif/util/hwMemLib.h>
|
||
|
#include <hwif/vxbus/vxBus.h>
|
||
|
#include <hwif/vxbus/vxbPlbLib.h>
|
||
|
#include <hwif/vxbus/hwConf.h>
|
||
|
#include <../src/hwif/h/vxbus/vxbAccess.h>
|
||
|
|
||
|
/*#define INCLUDE_ANSI_ESC_SEQUENCE*/
|
||
|
|
||
|
#include "vxbM6845Vga.h"
|
||
|
|
||
|
/* VxBus structures and methods */
|
||
|
/* imports */
|
||
|
IMPORT TY_DEV * pcConDevBind (int, FUNCPTR, void *);
|
||
|
UINT32 pcConframeBufferAddr;
|
||
|
|
||
|
|
||
|
/* locals */
|
||
|
LOCAL UINT32 defaultFbBase = 0;
|
||
|
LOCAL size_t tyWrtThreshold = 20;
|
||
|
|
||
|
LOCAL BOOL m6845vxbProbe (VXB_DEVICE_ID pDev);
|
||
|
LOCAL void m6845vxbInstInit (VXB_DEVICE_ID pDev);
|
||
|
LOCAL void m6845vxbInstInit2 (VXB_DEVICE_ID pDev);
|
||
|
LOCAL void m6845vxbInstConnect (VXB_DEVICE_ID pDev);
|
||
|
|
||
|
LOCAL struct drvBusFuncs m6845vxbFuncs =
|
||
|
{
|
||
|
m6845vxbInstInit, /* devInstanceInit */
|
||
|
m6845vxbInstInit2, /* devInstanceInit2 */
|
||
|
m6845vxbInstConnect /* devConnect */
|
||
|
};
|
||
|
|
||
|
LOCAL void m6845ScreenRevMethod (VXB_DEVICE_ID, int);
|
||
|
LOCAL void m6845CurAttribMethod (VXB_DEVICE_ID, int);
|
||
|
LOCAL void m6845CursorSetMethod (VXB_DEVICE_ID, int);
|
||
|
LOCAL void m6845CursorMoveMethod (VXB_DEVICE_ID, int);
|
||
|
|
||
|
LOCAL struct vxbDeviceMethod m6845VgaMethods[] =
|
||
|
{
|
||
|
DEVMETHOD(vgaScreenRev, m6845ScreenRevMethod),
|
||
|
DEVMETHOD(vgaCurAttrib, m6845CurAttribMethod),
|
||
|
DEVMETHOD(vgaCursorSet, m6845CursorSetMethod),
|
||
|
DEVMETHOD(vgaCursorMove, m6845CursorMoveMethod),
|
||
|
{0, 0}
|
||
|
};
|
||
|
|
||
|
LOCAL struct vxbDevRegInfo m6845vxbDevRegistration =
|
||
|
{
|
||
|
NULL, /* pNext */
|
||
|
VXB_DEVID_DEVICE, /* devID */
|
||
|
VXB_BUSID_PLB, /* busID = PLB */
|
||
|
VXB_VER_4_0_0, /* vxbVersion */
|
||
|
"m6845Vga", /* drvName */
|
||
|
&m6845vxbFuncs, /* pDrvBusFuncs */
|
||
|
m6845VgaMethods, /* pMethods */
|
||
|
m6845vxbProbe /* devProbe */
|
||
|
};
|
||
|
|
||
|
LOCAL UCHAR * m6845CharTable [] =
|
||
|
{
|
||
|
/* 8-bit Latin-1 mapped to the PC charater set: '\0' means non-printable */
|
||
|
(unsigned char *)
|
||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||
|
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||
|
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||
|
"`abcdefghijklmnopqrstuvwxyz{|}~\0"
|
||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||
|
"\040\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
|
||
|
"\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
|
||
|
"\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
|
||
|
"\376\245\376\376\376\376\231\376\235\376\376\376\232\376\376\341"
|
||
|
"\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
|
||
|
"\376\244\225\242\223\376\224\366\233\227\243\226\201\376\376\230",
|
||
|
/* vt100 graphics */
|
||
|
(unsigned char *)
|
||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||
|
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||
|
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ "
|
||
|
"\004\261\007\007\007\007\370\361\040\007\331\277\332\300\305\007"
|
||
|
"\007\304\007\007\303\264\301\302\263\007\007\007\007\007\234\0"
|
||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||
|
"\040\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
|
||
|
"\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
|
||
|
"\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
|
||
|
"\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341"
|
||
|
"\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
|
||
|
"\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230",
|
||
|
/* IBM graphics: minimal translations (CR, LF, LL, SO, SI and ESC) */
|
||
|
(unsigned char *)
|
||
|
"\000\001\002\003\004\005\006\007\010\011\000\013\000\000\000\000"
|
||
|
"\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037"
|
||
|
"\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
|
||
|
"\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
|
||
|
"\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
|
||
|
"\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
|
||
|
"\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
|
||
|
"\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
|
||
|
"\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
|
||
|
"\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
|
||
|
"\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
|
||
|
"\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
|
||
|
"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
|
||
|
"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
|
||
|
"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
|
||
|
"\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"
|
||
|
};
|
||
|
|
||
|
|
||
|
/* forward declarations */
|
||
|
|
||
|
LOCAL void m6845HrdInit (M6845_CON_DEV *);
|
||
|
LOCAL void m6845StatInit (M6845_CON_DEV *);
|
||
|
LOCAL int m6845WriteString (M6845_CON_DEV *);
|
||
|
|
||
|
/******************************************************************************
|
||
|
*
|
||
|
* m6845HrdInit - initialize the VGA Display
|
||
|
*
|
||
|
* This function is called externally to initialize the m6845 display
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*
|
||
|
* NOMANUAL
|
||
|
*/
|
||
|
#define PCCON_BUFFER_SIZE (1*1024*1024)
|
||
|
LOCAL void m6845HrdInit
|
||
|
(
|
||
|
M6845_CON_DEV * pDrvCtrl
|
||
|
)
|
||
|
{
|
||
|
|
||
|
pcConframeBufferAddr = (UINT32)cacheDmaMalloc(PCCON_BUFFER_SIZE);
|
||
|
defaultFbBase = pcConframeBufferAddr;
|
||
|
m6845StatInit (pDrvCtrl);
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
*
|
||
|
* m6845StatInit - initialize the VGA Display state
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845StatInit
|
||
|
(
|
||
|
M6845_CON_DEV * pDrvCtrl
|
||
|
)
|
||
|
{
|
||
|
HCF_DEVICE * pHcf = hcfDeviceGet (pDrvCtrl->pDev);
|
||
|
|
||
|
pDrvCtrl->memBase = (void*)defaultFbBase;
|
||
|
|
||
|
devResourceGet (pHcf, "colorMode", HCF_RES_INT, (void *)&pDrvCtrl->colorMode);
|
||
|
if (pDrvCtrl->colorMode == COLOR)
|
||
|
pDrvCtrl->defAttrib = ATRB_FG_BRIGHTWHITE | ATRB_BG_BROWN;
|
||
|
else
|
||
|
pDrvCtrl->defAttrib = ATRB_FG_WHITE | ATRB_BG_BLACK;
|
||
|
|
||
|
devResourceGet (pHcf, "colorSetting", HCF_RES_INT, (void *)&pDrvCtrl->defAttrib);
|
||
|
|
||
|
pDrvCtrl->sv_curAttrib = pDrvCtrl->defAttrib;
|
||
|
pDrvCtrl->curAttrib = pDrvCtrl->defAttrib;
|
||
|
|
||
|
pDrvCtrl->sv_col = pDrvCtrl->col = 0;
|
||
|
pDrvCtrl->sv_row = pDrvCtrl->row = 0;
|
||
|
|
||
|
pDrvCtrl->curChrPos = pDrvCtrl->memBase; /* current position */
|
||
|
pDrvCtrl->sv_rev = pDrvCtrl->rev = FALSE;
|
||
|
|
||
|
pDrvCtrl->ncol = (screen_size_x/2/8); /* Number of columns */
|
||
|
pDrvCtrl->nrow = screen_size_y/16; /* Number of text rows */
|
||
|
pDrvCtrl->scst = 0; /* scroll start */
|
||
|
pDrvCtrl->sced = screen_size_y/16-1; /* scroll end */
|
||
|
pDrvCtrl->autoWrap = TRUE; /* auto Wrap mode */
|
||
|
pDrvCtrl->scrollCheck = FALSE; /* scroll flag off */
|
||
|
pDrvCtrl->charSet = m6845CharTable [TEXT_SET]; /* character set */
|
||
|
pDrvCtrl->vgaMode = TEXT_MODE; /* video mode */
|
||
|
pDrvCtrl->insMode = INSERT_MODE_OFF; /* insert mode */
|
||
|
pDrvCtrl->escParaCount = 0; /* zero parameters */
|
||
|
pDrvCtrl->escQuestion = FALSE; /* ? flag set to false */
|
||
|
bzero ((char *)pDrvCtrl->escPara, sizeof(pDrvCtrl->escPara));
|
||
|
bzero (pDrvCtrl->tab_stop, sizeof(pDrvCtrl->tab_stop));
|
||
|
pDrvCtrl->tab_stop [ 0] = 1;
|
||
|
pDrvCtrl->tab_stop [ 8] = 1;
|
||
|
pDrvCtrl->tab_stop [16] = 1;
|
||
|
pDrvCtrl->tab_stop [24] = 1;
|
||
|
pDrvCtrl->tab_stop [32] = 1;
|
||
|
pDrvCtrl->tab_stop [40] = 1;
|
||
|
pDrvCtrl->tab_stop [48] = 1;
|
||
|
pDrvCtrl->tab_stop [56] = 1;
|
||
|
pDrvCtrl->tab_stop [64] = 1;
|
||
|
pDrvCtrl->tab_stop [72] = 1;
|
||
|
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
*
|
||
|
* m6845ScreenRev - Reverse Screen
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845ScreenRev
|
||
|
(
|
||
|
FAST M6845_CON_DEV * pDrvCtrl /* pointer to the m6845 descriptor */
|
||
|
)
|
||
|
{
|
||
|
UCHAR * cp; /* to hold the current pointer */
|
||
|
UCHAR atr; /* to hold the attribute character */
|
||
|
|
||
|
for (cp = pDrvCtrl->memBase; cp < pDrvCtrl->memBase + 2000 * 2;
|
||
|
cp += 2)
|
||
|
{
|
||
|
atr = *(cp+1);
|
||
|
*(cp+1) = atr & INT_BLINK_MASK;
|
||
|
*(cp+1) |= (atr << 4) & BG_ATTR_MASK;
|
||
|
*(cp+1) |= (atr >> 4) & FG_ATTR_MASK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
*
|
||
|
* m6845CursorPos - Put the cursor at a specified location
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845CursorPos
|
||
|
(
|
||
|
M6845_CON_DEV * pDrvCtrl,
|
||
|
FAST UINT16 pos /* position of the cursor */
|
||
|
)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
*
|
||
|
* m6845CursorOn - switch the cursor on
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845CursorOn
|
||
|
(
|
||
|
M6845_CON_DEV * pDrvCtrl
|
||
|
)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
*
|
||
|
* m6845CursorOff - switch the cursor off
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845CursorOff
|
||
|
(
|
||
|
M6845_CON_DEV * pDrvCtrl
|
||
|
)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
/* VxBus routines */
|
||
|
|
||
|
/******************************************************************************
|
||
|
*
|
||
|
* m6845vxbRegister - register m6845vxb driver
|
||
|
*
|
||
|
* This routine registers the m6845vxb driver and device recognition
|
||
|
* data with the vxBus subsystem.
|
||
|
*
|
||
|
* NOTE:
|
||
|
*
|
||
|
* This routine is called early during system initialization, and
|
||
|
* *MUST NOT* make calls to OS facilities such as memory allocation
|
||
|
* and I/O.
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*
|
||
|
* ERRNO
|
||
|
*/
|
||
|
|
||
|
void m6845vxbRegister(void)
|
||
|
{
|
||
|
vxbDevRegister(&m6845vxbDevRegistration);
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
*
|
||
|
* m6845vxbProbe - probe for device presence
|
||
|
*
|
||
|
* NOTE:
|
||
|
*
|
||
|
* This routine is called early during system initialization, and
|
||
|
* *MUST* *NOT* make calls to OS facilities such as memory allocation
|
||
|
* and I/O.
|
||
|
*
|
||
|
* RETURNS: TRUE if probe passes and assumed a valid m6845vxb
|
||
|
* (or compatible) device. FALSE otherwise.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
LOCAL BOOL m6845vxbProbe
|
||
|
(
|
||
|
VXB_DEVICE_ID pDev /* Device information */
|
||
|
)
|
||
|
{
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
*
|
||
|
* m6845vxbInstInit - initialize m6845vxb device
|
||
|
*
|
||
|
* This is the m6845vxb initialization routine.
|
||
|
*
|
||
|
* NOTE:
|
||
|
*
|
||
|
* This routine is called early during system initialization, and
|
||
|
* *MUST NOT* make calls to OS facilities such as memory allocation
|
||
|
* and I/O.
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*
|
||
|
* ERRNO
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845vxbInstInit
|
||
|
(
|
||
|
VXB_DEVICE_ID pDev
|
||
|
)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
*
|
||
|
* m6845vxbInstInit2 - initialize m6845vxb device
|
||
|
*
|
||
|
* This is the m6845vxb initialization routine.
|
||
|
*
|
||
|
* NOTE:
|
||
|
*
|
||
|
* This routine is called early during system initialization, and
|
||
|
* *MUST NOT* make calls to OS facilities such as memory allocation
|
||
|
* and I/O.
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*
|
||
|
* ERRNO
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845vxbInstInit2
|
||
|
(
|
||
|
VXB_DEVICE_ID pDev
|
||
|
)
|
||
|
{
|
||
|
M6845_CON_DEV * pDrvCtrl = (M6845_CON_DEV *) malloc (sizeof (M6845_CON_DEV));
|
||
|
pDrvCtrl->pDev = pDev;
|
||
|
pDev->pDrvCtrl = pDrvCtrl;
|
||
|
pDev->pMethods = m6845VgaMethods;
|
||
|
|
||
|
vxbRegMap (pDev, 0, &pDrvCtrl->regHandle);
|
||
|
|
||
|
m6845HrdInit (pDrvCtrl);
|
||
|
|
||
|
}
|
||
|
|
||
|
/******************************************************************************
|
||
|
*
|
||
|
* m6845vxbInstConnect - connect m6845vxb device
|
||
|
*
|
||
|
* This is the m6845vxb connect routine.
|
||
|
*
|
||
|
* NOTE:
|
||
|
*
|
||
|
* This routine is called early during system initialization, and
|
||
|
* *MUST NOT* make calls to OS facilities such as memory allocation
|
||
|
* and I/O.
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*
|
||
|
* ERRNO
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845vxbInstConnect
|
||
|
(
|
||
|
VXB_DEVICE_ID pDev
|
||
|
)
|
||
|
{
|
||
|
M6845_CON_DEV * pDrvCtrl = pDev->pDrvCtrl;
|
||
|
pDrvCtrl->pTyDev = pcConDevBind (pDev->unitNumber,
|
||
|
m6845WriteString, (void *) pDrvCtrl);
|
||
|
}
|
||
|
|
||
|
void draw_char(unsigned char c, int x, int y)
|
||
|
{
|
||
|
int i,j;
|
||
|
unsigned char *VGA_DEV;
|
||
|
unsigned char *base;
|
||
|
unsigned char line;
|
||
|
VGA_DEV = (unsigned char *)(defaultFbBase + DEFAULT_FB_MEM);
|
||
|
base = &((VGA_DEV)[y*screen_size_x + x * depth]);
|
||
|
|
||
|
|
||
|
|
||
|
for(i=0; i<CHAR_HEIGHT; i++) {
|
||
|
line = FONT[c * CHAR_HEIGHT + i];
|
||
|
|
||
|
for(j=CHAR_WIDTH * depth; j > 0; j -= 2 ) {
|
||
|
base[ j ] = (line & 0x1) ? draw_color_1 : back_color_1;
|
||
|
base[ j - 1] = (line & 0x1) ? draw_color_2 : back_color_2;
|
||
|
line = line >> 1;
|
||
|
}
|
||
|
base += screen_size_x;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LOCAL char pre = -1;
|
||
|
|
||
|
void fb_putchar(M6845_CON_DEV * pVgaConDv, char c)
|
||
|
{
|
||
|
if(defaultFbBase == 0)
|
||
|
return;
|
||
|
if (c == '\n') {
|
||
|
if(pre != '\r')
|
||
|
{
|
||
|
draw_char('\0', pVgaConDv->col * CHAR_WIDTH , pVgaConDv->row * CHAR_HEIGHT);
|
||
|
}
|
||
|
|
||
|
pVgaConDv->col = 0;
|
||
|
pVgaConDv->row++;
|
||
|
}
|
||
|
else if (c == '\r') {
|
||
|
draw_char('\0', pVgaConDv->col * CHAR_WIDTH , pVgaConDv->row * CHAR_HEIGHT);
|
||
|
pVgaConDv->col = 0;
|
||
|
}
|
||
|
else if (c== '\t') {
|
||
|
/*pVgaConDv->col += 8;*/
|
||
|
}
|
||
|
else if (c == '\b'){
|
||
|
draw_char('\0', pVgaConDv->col * CHAR_WIDTH , pVgaConDv->row * CHAR_HEIGHT);
|
||
|
pVgaConDv->col--;
|
||
|
draw_char('\0', pVgaConDv->col * CHAR_WIDTH , pVgaConDv->row * CHAR_HEIGHT);
|
||
|
}
|
||
|
else {
|
||
|
draw_char(c, pVgaConDv->col * CHAR_WIDTH , pVgaConDv->row * CHAR_HEIGHT);
|
||
|
pVgaConDv->col++;
|
||
|
}
|
||
|
if(pVgaConDv->col > (pVgaConDv->ncol-1)) {
|
||
|
pVgaConDv->col = 0;
|
||
|
pVgaConDv->row++;
|
||
|
}
|
||
|
|
||
|
#ifdef LITTLE_WINDOWS
|
||
|
if(pVgaConDv->row >= pVgaConDv->nrow) {
|
||
|
memcpy(defaultFbBase + (CHAR_HEIGHT * (num_rows - lw_rows)) * screen_size_x,
|
||
|
defaultFbBase + (CHAR_HEIGHT * (num_rows - lw_rows + 1)) * screen_size_x,
|
||
|
screen_size_x * (CHAR_HEIGHT * (lw_rows - 1)));
|
||
|
memset(pVgaConDv->nrow + (CHAR_HEIGHT * (num_rows - 1)) * screen_size_x, 0, screen_size_x * CHAR_HEIGHT);
|
||
|
pVgaConDv->row--;
|
||
|
}
|
||
|
#else
|
||
|
if(pVgaConDv->row >=pVgaConDv->nrow) {
|
||
|
memcpy((void*)defaultFbBase, (void*)(defaultFbBase + screen_size_x*CHAR_HEIGHT), screen_size_x * screen_size_y - screen_size_x*CHAR_HEIGHT);
|
||
|
pVgaConDv->row--;
|
||
|
memset((void*)defaultFbBase + (/*592*/pVgaConDv->nrow*16-16)*screen_size_x, 0, screen_size_x*CHAR_HEIGHT);
|
||
|
}
|
||
|
#endif
|
||
|
if(c != '\r')
|
||
|
{
|
||
|
draw_char(95/*219*/, pVgaConDv->col * CHAR_WIDTH, pVgaConDv->row * CHAR_HEIGHT);
|
||
|
}
|
||
|
pre = c;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
*
|
||
|
* m6845WriteString - Write Character string to VGA Display
|
||
|
*
|
||
|
* This function does the write to the m6845 routine. This routine is provided as
|
||
|
* transmitter startup routine when tyDevInit is called.
|
||
|
*
|
||
|
* RETURNS: number of bytes written to the screen
|
||
|
*
|
||
|
* NOMANUAL
|
||
|
*/
|
||
|
LOCAL int m6845WriteString
|
||
|
(
|
||
|
M6845_CON_DEV * pDrvCtrl /* pointer to the console descriptor */
|
||
|
)
|
||
|
{
|
||
|
int dummy;
|
||
|
UCHAR ch;
|
||
|
FAST int nBytes;
|
||
|
FAST UCHAR atr;
|
||
|
TY_DEV * pTyDev = pDrvCtrl->pTyDev;
|
||
|
FAST RING_ID ringId = pTyDev->wrtBuf;
|
||
|
|
||
|
M6845_LOCK_TAKE(pDrvCtrl);
|
||
|
pTyDev->wrtState.busy = TRUE;
|
||
|
atr = pDrvCtrl->curAttrib;
|
||
|
nBytes = 0;
|
||
|
/* check if we need to output XON/XOFF for the read side */
|
||
|
|
||
|
if (pTyDev->wrtState.xoff || pTyDev->wrtState.flushingWrtBuf)
|
||
|
{
|
||
|
pTyDev->wrtState.busy = FALSE;
|
||
|
M6845_LOCK_GIVE(pDrvCtrl);
|
||
|
return nBytes;
|
||
|
}
|
||
|
while (RNG_ELEM_GET (ringId,&ch,dummy) != 0)
|
||
|
{
|
||
|
nBytes++;
|
||
|
fb_putchar(pDrvCtrl, ch);
|
||
|
}
|
||
|
|
||
|
pTyDev->wrtState.busy = FALSE;
|
||
|
M6845_LOCK_GIVE(pDrvCtrl);
|
||
|
|
||
|
if (rngFreeBytes (ringId) >= tyWrtThreshold)
|
||
|
{
|
||
|
semGive (&pTyDev->wrtSyncSem);
|
||
|
|
||
|
if (_func_selWakeupAll != NULL)
|
||
|
(* _func_selWakeupAll) (&pTyDev->selWakeupList, SELWRITE);
|
||
|
}
|
||
|
return nBytes;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*******************************************************************************
|
||
|
*
|
||
|
* m6845ScreenRevMethod - reverse the screen (method)
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*
|
||
|
* NOMANUAL
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845ScreenRevMethod
|
||
|
(
|
||
|
VXB_DEVICE_ID pDev,
|
||
|
int value
|
||
|
)
|
||
|
{
|
||
|
M6845_CON_DEV * pDrvCtrl = pDev->pDrvCtrl;
|
||
|
VGA_QUERY * pQuery = (VGA_QUERY *) value;
|
||
|
|
||
|
if (pQuery->unit != pDev->unitNumber)
|
||
|
return;
|
||
|
|
||
|
pDrvCtrl->rev = pDrvCtrl->rev ? FALSE : TRUE;
|
||
|
|
||
|
m6845ScreenRev (pDrvCtrl);
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
*
|
||
|
* m6845CurAttribMethod - get or set the color attributes (method)
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*
|
||
|
* NOMANUAL
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845CurAttribMethod
|
||
|
(
|
||
|
VXB_DEVICE_ID pDev,
|
||
|
int value
|
||
|
)
|
||
|
{
|
||
|
M6845_CON_DEV * pDrvCtrl = pDev->pDrvCtrl;
|
||
|
VGA_QUERY * pQuery = (VGA_QUERY *) value;
|
||
|
|
||
|
if (pQuery->unit != pDev->unitNumber)
|
||
|
return;
|
||
|
|
||
|
if (pQuery->get)
|
||
|
*pQuery->pArg = pDrvCtrl->curAttrib;
|
||
|
else
|
||
|
pDrvCtrl->curAttrib = *pQuery->pArg;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
*
|
||
|
* m6845CursorSetMethod - turn the cursor off or on (method)
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*
|
||
|
* NOMANUAL
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845CursorSetMethod
|
||
|
(
|
||
|
VXB_DEVICE_ID pDev,
|
||
|
int value
|
||
|
)
|
||
|
{
|
||
|
M6845_CON_DEV * pDrvCtrl = pDev->pDrvCtrl;
|
||
|
VGA_QUERY * pQuery = (VGA_QUERY *) value;
|
||
|
|
||
|
if (pQuery->unit != pDev->unitNumber)
|
||
|
return;
|
||
|
|
||
|
if (*pQuery->pArg == 0)
|
||
|
m6845CursorOff (pDrvCtrl);
|
||
|
else
|
||
|
m6845CursorOn (pDrvCtrl);
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
*
|
||
|
* m6845CursorMoveMethod - move the cursor (method)
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*
|
||
|
* NOMANUAL
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845CursorMoveMethod
|
||
|
(
|
||
|
VXB_DEVICE_ID pDev,
|
||
|
int value
|
||
|
)
|
||
|
{
|
||
|
M6845_CON_DEV * pDrvCtrl = pDev->pDrvCtrl;
|
||
|
VGA_QUERY * pQuery = (VGA_QUERY *) value;
|
||
|
int arg = *pQuery->pArg;
|
||
|
|
||
|
if (pQuery->unit != pDev->unitNumber)
|
||
|
return;
|
||
|
|
||
|
pDrvCtrl->row = (arg >> 8) & 0xff;
|
||
|
pDrvCtrl->col = arg & 0xff;
|
||
|
if (pDrvCtrl->row >= pDrvCtrl->nrow)
|
||
|
pDrvCtrl->row = pDrvCtrl->nrow - 1;
|
||
|
|
||
|
if (pDrvCtrl->col >= pDrvCtrl->ncol)
|
||
|
pDrvCtrl->col = pDrvCtrl->ncol - 1;
|
||
|
|
||
|
m6845CursorPos (pDrvCtrl, (UINT16) (pDrvCtrl->row * pDrvCtrl->ncol
|
||
|
+ pDrvCtrl->col));
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifdef INCLUDE_ANSI_ESC_SEQUENCE
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* m6845EscResponse - This function gives back a response to an escape sequence.
|
||
|
* The valid response Ids are
|
||
|
* 0 for cursor position, 1 for terminal status,
|
||
|
* 2 for terminal device attributes.
|
||
|
*
|
||
|
* RETURNS: N/A
|
||
|
*/
|
||
|
|
||
|
LOCAL void m6845EscResponse
|
||
|
(
|
||
|
M6845_CON_DEV * pDrvCtrl, /* pointer to the m6845 descriptor */
|
||
|
int responseId /* response Id */
|
||
|
)
|
||
|
{
|
||
|
tyIoctl (pDrvCtrl->pTyDev, FIORFLUSH, 0);
|
||
|
|
||
|
if ( responseId == 0)
|
||
|
{
|
||
|
sprintf (pDrvCtrl->escResp, "\033[%d;%dR", pDrvCtrl->row,
|
||
|
pDrvCtrl->col);
|
||
|
}
|
||
|
else if ( responseId == 1)
|
||
|
{
|
||
|
sprintf (pDrvCtrl->escResp, "\033[0n");
|
||
|
}
|
||
|
else if ( responseId == 2)
|
||
|
{
|
||
|
sprintf (pDrvCtrl->escResp, "\033[?1;0c");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pDrvCtrl->escResp[0] = '\0';
|
||
|
}
|
||
|
|
||
|
rngBufPut (pDrvCtrl->pTyDev->rdBuf, pDrvCtrl->escResp,
|
||
|
strlen (pDrvCtrl->escResp) );
|
||
|
semGive (&pDrvCtrl->pTyDev->rdSyncSem);
|
||
|
selWakeupAll (&pDrvCtrl->pTyDev->selWakeupList, SELREAD);
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif /* INCLUDE_ANSI_ESC_SEQUENCE */
|