/* Copyright 1992 by Holger Veit
* May be freely used with Bill Jolitz's port of
* 386bsd and may be included in a 386bsd collection
* as long as binary and source are available and reproduce the above
* You may freely modify this code and contribute improvements based
* on this code as long as you don't claim to be the original author.
* Commercial use of this source requires permittance of the copyright
* holder. A general license for 386bsd will override this restriction.
* Use at your own risk. The copyright holder or any person who makes
* this code available for the public (administrators of public archives
* for instance) are not responsible for any harm to hardware or software
* that might happen due to wrong application or program faults.
* @(#) $RCSfile$ $Revision$ (Contributed to 386bsd) $Date$
* History: see CO_HISTORY
static char *rcsid
= "$Header$";
/* This file provides a real mini terminal emulator, basically one that
* has only the cursor functions, screen clear/home, DEL, TAB, BEL,
* This interface is used for a installation kernel which must be
* small enough to fit on a diskette.
/* check my optional symbol to avoid multiple inclusions */
#define ESC_NONE 0 /* No esc in progress */
#define ESC_WBRAC 1 /* got esc, wait for '[' or 'c' */
#define ESC_WPARAM 2 /* got esc [, wait for param, ';' or letter */
* Do the local initialisations. Notice that many things are already done
/* fill the cons_capabilities structure
xc
= cons_capabilities
.emul_name
;
while (*xc
++ = xc_char2xc(*c
++)) ;
#define copydef(src,dst)\
xc_bcopy(src,dst,KBDDEFOVLKEYSIZE)
* this routine does all the ESC and character processing stuff
void vtemul_exec(struct vty
*vp
, XCHAR ch
)
int sc
= 1; /* do scroll check */
struct outmode
*sk
= vp
->op
;
/* which attributes do we use? */
at
= sk
->fg_at
|sk
->bg_at
;
/* translate to proper font */
ch
= vga_xlatiso646(vp
,&at
,&sat
,ch
);
if(sk
->escstate
!= ESC_NONE
)
sk
->escstate
= ESC_WBRAC
;
inccol
= (8 - vp
->col
% 8); /* non-destructive tab */
emul_cursorrelative(vp
,inccol
,0);
emul_cursorrelative(vp
,-vp
->col
,0);
emul_cursorrelative(vp
,0,1);
/* different sounds for different vtys possible */
sysbeep (vp
->pitch
, vp
->duration
);
/* NO ESC, normal processing */
emul_wrtchar(vp
,ch
,vp
->so
? sat
: at
);
if (vp
->col
>= vp
->ncol
) vp
->col
= 0;
/* has seen ESC, wait for [ or 'c' */
sk
->escstate
= ESC_WPARAM
;
/* Clear screen & home */
emul_cursormove(vp
, 0, 0);
emul_wrtchar(vp
, ch
, sat
);
case ESC_WPARAM
: /* has seen ESC [ wait for digit, ';' or letter */
if (ch
>='0' && ch
<='9') {
sk
->param
[sk
->parcnt
] *= 10;
sk
->param
[sk
->parcnt
] += ch
-'0';
sk
->escstate
= ESC_NONE
; /* error */
sk
->param
[sk
->parcnt
] = 0;
else if (ch
>=' ' && ch
<='~') {
sk
->param
[sk
->parcnt
] = 0;
case 'A': /* back cx rows */
case 'B': /* down cx rows */
emul_cursordown(vp
, par1
);
case 'C': /* right cursor */
emul_cursorright(vp
, par1
, 1);
case 'D': /* left cursor */
emul_cursorleft(vp
, par1
);
case 'H': /* Cursor move */
emul_cursormove(vp
, par1
, par2
);
if (sc
&& emul_checkcursor(vp
) > 0) {
if (consoftc
.cs_flags
&CO_OPEN
)
* The following part provides a basic set of ioctls
int consioctl(dev_t dev
, int cmd
, caddr_t data
, int flag
)
register struct tty
*tp
= dev2tty(dev
);
*((struct consinfo
*)data
) = cons_capabilities
;
} else if (cmd
==OLDCONSGINFO
) {
((struct oldconsinfo
*)data
)->info1
= cons_capabilities
.info1
;
error
= (*linesw
[tp
->t_line
].l_ioctl
)(tp
, cmd
, data
, flag
);
error
= ttioctl(tp
, cmd
, data
, flag
);
/* must be executed for backward compatibility
* must be executed *after* the tty ioctls,
* because it shares an essential ioctl with them.
error
= kbdioctl(dev
, cmd
, data
, flag
);
return error
==0 ? 0 : ENOTTY
;
* process keyboard ioctls
int kbdioctl(dev_t dev
, int cmd
, caddr_t data
, int flag
)
struct vty
*vp
= dev2vty(dev
);
/* CONSGINFO is mandatory ! */
*((struct consinfo
*)data
) = cons_capabilities
;
((struct oldconsinfo
*)data
)->info1
= cons_capabilities
.info1
;
/* this is a relic from my youth mistakes */
return kbd_getckeydef (((Ovl_tbl
*)data
)->keynum
, (Ovl_tbl
*) data
);
return kbd_setkeydef((Ovl_tbl
*)data
);
return kbd_getokeydef (((Ovl_tbl
*)data
)->keynum
, (Ovl_tbl
*) data
);
return kbd_rmkeydef (*(int *) data
);
kbs
.a0flag
= (*(int*)data
& 1) != 0;
kbs
.c0flag
= (*(int*)data
& 2) != 0;
kbs
.m0flag
= (*(int*)data
& 4) != 0; /*not used yet*/
/* backward compatibility */
error
= vgaioctl(dev
, cmd
, data
, flag
);
static int vioc_setfontmap(struct fontmap
*data
)
u_char
*ofs
= (u_char
*)Crtat
+pg
*0x4000;
if (vds
.cardtype
< VG_EGA
|| pg
< 0 || pg
> 7) return EINVAL
;
vds
.encoding
[pg
] = data
->encoding
;
for(i
=k
=0; i
<(VGA_FNTCSIZE
*VGA_FNTNCHARS
); k
+=32,i
+=VGA_FNTCSIZE
) {
bcopy(&data
->map
[i
],ofs
+k
,VGA_FNTCSIZE
);
/* enable SB/SBH when font 1 is loaded */
if (pg
==1 && data
->encoding
!= NOFONT
) outw(0x3c4,0x0403); /* SA=1,SB=0 */
static int vioc_getfontmap(struct fontmap
*data
)
u_char
*ofs
= (u_char
*)Crtat
+ pg
*0x4000;
if (vds
.cardtype
< VG_EGA
|| pg
< 0 || pg
> 1) return EINVAL
;
data
->encoding
= vds
.encoding
[pg
];
for(i
=k
=0; i
<(VGA_FNTCSIZE
*VGA_FNTNCHARS
); k
+=32,i
+=VGA_FNTCSIZE
)
bcopy(ofs
+k
,&data
->map
[i
],VGA_FNTCSIZE
);
* execute my own vga ioctls
int vgaioctl(dev_t dev
, int cmd
, caddr_t data
, int flag
)
/* CONSGINFO is mandatory ! */
*((struct consinfo
*)data
) = cons_capabilities
;
((struct oldconsinfo
*)data
)->info1
= cons_capabilities
.info1
;
return kbd_setxserveriopl(*(int*)data
);
return vga_getvideoinfo((struct videoinfo
*)data
);
return vioc_setfontmap((struct fontmap
*)data
);
return vioc_getfontmap((struct fontmap
*)data
);