syscons.c revision 5572
1162922Sariff/*- 2162922Sariff * Copyright (c) 1992-1995 S�ren Schmidt 3162922Sariff * Copyright (c) 1990 The Regents of the University of California. 4182999Smav * All rights reserved. 5162922Sariff * 6162922Sariff * This code is derived from software contributed to Berkeley by 7162922Sariff * William Jolitz and Don Ahn. 8162922Sariff * 9162922Sariff * Redistribution and use in source and binary forms, with or without 10162922Sariff * modification, are permitted provided that the following conditions 11162922Sariff * are met: 12162922Sariff * 1. Redistributions of source code must retain the above copyright 13162922Sariff * notice, this list of conditions and the following disclaimer 14162922Sariff * in this position and unchanged. 15162922Sariff * 2. Redistributions in binary form must reproduce the above copyright 16162922Sariff * notice, this list of conditions and the following disclaimer in the 17162922Sariff * documentation and/or other materials provided with the distribution. 18162922Sariff * 3. All advertising materials mentioning features or use of this software 19162922Sariff * must display the following acknowledgement: 20162922Sariff * This product includes software developed by the University of 21162922Sariff * California, Berkeley and its contributors. 22162922Sariff * 4. Neither the name of the University nor the names of its contributors 23162922Sariff * may be used to endorse or promote products derived from this software 24162922Sariff * without specific prior written permission. 25162922Sariff * 26162922Sariff * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27162922Sariff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28162922Sariff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29162922Sariff * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30162922Sariff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31162922Sariff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32162922Sariff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33162922Sariff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34162922Sariff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35162922Sariff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36162922Sariff * SUCH DAMAGE. 37162922Sariff * 38162922Sariff * $Id: syscons.c,v 1.91 1995/01/13 03:19:22 ache Exp $ 39162922Sariff */ 40162922Sariff 41162922Sariff#include "sc.h" 42162922Sariff 43162922Sariff#if NSC > 0 44162922Sariff 45162922Sariff#include <sys/param.h> 46162922Sariff#include <sys/systm.h> 47164614Sariff#include <sys/conf.h> 48162922Sariff#include <sys/ioctl.h> 49162922Sariff#include <sys/proc.h> 50162922Sariff#include <sys/user.h> 51162922Sariff#include <sys/tty.h> 52162922Sariff#include <sys/uio.h> 53162922Sariff#include <sys/callout.h> 54162922Sariff#include <sys/kernel.h> 55162922Sariff#include <sys/syslog.h> 56162922Sariff#include <sys/errno.h> 57162922Sariff#include <sys/malloc.h> 58162922Sariff#include <sys/devconf.h> 59162922Sariff 60162922Sariff#include <machine/clock.h> 61162922Sariff#include <machine/console.h> 62162922Sariff#include <machine/psl.h> 63162922Sariff#include <machine/frame.h> 64182999Smav#include <machine/pc/display.h> 65162922Sariff 66162922Sariff#include <i386/isa/isa.h> 67162922Sariff#include <i386/isa/isa_device.h> 68162922Sariff#include <i386/isa/timerreg.h> 69162922Sariff#include <i386/isa/kbdtables.h> 70162922Sariff#include <i386/i386/cons.h> 71193640Sariff 72193640Sariff#if !defined(MAXCONS) 73193640Sariff#define MAXCONS 12 74193640Sariff#endif 75162922Sariff 76162922Sariff/* this may break on older VGA's but is usefull on real 32 bit systems */ 77162922Sariff#define bcopyw bcopy 78162922Sariff 79171141Sariff#if defined(HARDFONTS) 80171141Sariff#include <i386/isa/iso8859.font> 81171141Sariff#endif 82162922Sariff 83162922Sariff/* vm things */ 84162922Sariff#define ISMAPPED(pa, width) \ 85162922Sariff (((pa) <= (u_long)0x1000 - (width)) \ 86162922Sariff || ((pa) >= 0xa0000 && (pa) <= 0x100000 - (width))) 87162922Sariff#define pa_to_va(pa) (KERNBASE + (pa)) /* works if ISMAPPED(pa...) */ 88162922Sariff 89204351Smav/* status flags */ 90162922Sariff#define LOCK_KEY_MASK 0x0000F 91162922Sariff#define LED_MASK 0x00007 92162922Sariff#define UNKNOWN_MODE 0x00010 93169277Sariff#define KBD_RAW_MODE 0x00020 94169277Sariff#define SWITCH_WAIT_REL 0x00040 95169277Sariff#define SWITCH_WAIT_ACQ 0x00080 96169277Sariff#define BUFFER_SAVED 0x00100 97193640Sariff 98162922Sariff/* configuration flags */ 99183097Smav#define BLINK_CURSOR 0x00001 100183097Smav#define VISUAL_BELL 0x00002 101183097Smav 102183097Smav/* video hardware memory addresses */ 103193640Sariff#define VIDEOMEM 0x000A0000 104183097Smav 105162965Sariff/* misc defines */ 106162922Sariff#define MAX_ESC_PAR 5 107162922Sariff#define LOAD 1 108162922Sariff#define SAVE 0 109162922Sariff#define COL 80 110162965Sariff#define ROW 25 111162965Sariff#define BELL_DURATION 5 112163057Sariff#define BELL_PITCH 800 113163057Sariff#define TIMER_FREQ 1193182 /* should be in isa.h */ 114162922Sariff#define CONSOLE_BUFSIZE 1024 115162965Sariff#define PCBURST 128 116163257Sariff#define FONT_8_LOADED 0x001 117163257Sariff#define FONT_14_LOADED 0x002 118163257Sariff#define FONT_16_LOADED 0x004 119163257Sariff#define HISTORY_SIZE 100*80 120163257Sariff 121163257Sariff/* defines related to hardware addresses */ 122162965Sariff#define MONO_BASE 0x3B4 /* crt controller base mono */ 123162965Sariff#define COLOR_BASE 0x3D4 /* crt controller base color */ 124162965Sariff#define MISC 0x3C2 /* misc output register */ 125169277Sariff#define ATC IO_VGA+0x00 /* attribute controller */ 126169277Sariff#define TSIDX IO_VGA+0x04 /* timing sequencer idx */ 127169277Sariff#define TSREG IO_VGA+0x05 /* timing sequencer data */ 128171141Sariff#define PIXMASK IO_VGA+0x06 /* pixel write mask */ 129171141Sariff#define PALRADR IO_VGA+0x07 /* palette read address */ 130171141Sariff#define PALWADR IO_VGA+0x08 /* palette write address */ 131171141Sariff#define PALDATA IO_VGA+0x09 /* palette data register */ 132171141Sariff#define GDCIDX IO_VGA+0x0E /* graph data controller idx */ 133171141Sariff#define GDCREG IO_VGA+0x0F /* graph data controller data */ 134171141Sariff 135171141Sariff/* special characters */ 136162922Sariff#define cntlc 0x03 137162922Sariff#define cntld 0x04 138162922Sariff#define bs 0x08 139162922Sariff#define lf 0x0a 140162922Sariff#define cr 0x0d 141162922Sariff#define del 0x7f 142162922Sariff 143211910Sjfvtypedef struct term_stat { 144218149Sjfv int esc; /* processing escape sequence */ 145221789Sjfv int num_param; /* # of parameters to ESC */ 146162922Sariff int last_param; /* last parameter # */ 147171330Sariff int param[MAX_ESC_PAR]; /* contains ESC parameters */ 148162922Sariff int cur_attr; /* current attributes */ 149163136Sariff int std_attr; /* normal attributes */ 150171330Sariff int rev_attr; /* reverse attributes */ 151197017Smav} term_stat; 152197017Smav 153187020Smavtypedef struct scr_stat { 154218149Sjfv u_short *crt_base; /* address of screen memory */ 155184207Smav u_short *scr_buf; /* buffer when off screen */ 156162922Sariff u_short *crtat; /* cursor address */ 157162922Sariff int xpos; /* current X position */ 158162922Sariff int ypos; /* current Y position */ 159162922Sariff int xsize; /* X size */ 160162922Sariff int ysize; /* Y size */ 161162922Sariff term_stat term; /* terminal emulation stuff */ 162173817Sariff char cursor_start; /* cursor start line # */ 163173817Sariff char cursor_end; /* cursor end line # */ 164173817Sariff char cursor_protect; /* protect cursor */ 165173817Sariff u_short cursor_saveunder; /* saved char under cursor */ 166173817Sariff u_char border; /* border color */ 167173817Sariff u_short bell_duration; 168186511Smav u_short bell_pitch; 169186511Smav u_short status; /* status (bitfield) */ 170186511Smav u_short mode; /* mode */ 171186511Smav pid_t pid; /* pid of controlling proc */ 172186511Smav struct proc *proc; /* proc* of controlling proc */ 173186511Smav struct vt_mode smode; /* switch mode */ 174186511Smav u_short history[HISTORY_SIZE]; 175186511Smav u_short *history_head; 176186511Smav u_short *history_pos; 177186511Smav} scr_stat; 178197018Smav 179197018Smavtypedef struct default_attr { 180197018Smav int std_attr; /* normal attributes */ 181197018Smav int rev_attr; /* reverse attributes */ 182162922Sariff} default_attr; 183162922Sariff 184162922Sariffstatic default_attr user_default = { 185162922Sariff (FG_LIGHTGREY | BG_BLACK) << 8, 186162922Sariff (FG_BLACK | BG_LIGHTGREY) << 8 187163136Sariff}; 188187020Smav 189187020Smavstatic default_attr kernel_default = { 190187020Smav (FG_WHITE | BG_BLACK) << 8, 191187020Smav (FG_BLACK | BG_LIGHTGREY) << 8 192187020Smav}; 193187020Smav 194187020Smavstatic scr_stat main_console; 195187020Smavstatic scr_stat *console[MAXCONS]; 196187020Smavstatic scr_stat *cur_console; 197187020Smavstatic scr_stat *new_scp, *old_scp; 198187020Smavstatic term_stat kernel_console; 199187020Smavstatic default_attr *current_default; 200187020Smav/* SOS 201162922Sariffstatic int console_buffer_count; 202162922Sariffstatic char console_buffer[CONSOLE_BUFSIZE]; 203216766Syongari*/ 204216766Syongaristatic char switch_in_progress = 0; 205216766Syongaristatic char blink_in_progress = 0; 206216766Syongaristatic char write_in_progress = 0; 207163136Sariffstatic char polling = 0; 208163136Sariffstatic u_short *crtat = 0; 209163136Sariffstatic u_int crtc_addr = MONO_BASE; 210163136Sariffstatic char crtc_vga = 0; 211163136Sariffstatic u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0; 212163136Sariffstatic u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0; 213163136Sariffstatic char *font_8 = NULL, *font_14 = NULL, *font_16 = NULL; 214163136Sariffstatic int fonts_loaded = 0; 215163136Sariffstatic char palette[3*256]; 216163136Sariffstatic const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab); 217186301Smav#if ASYNCH 218186301Smavstatic u_char kbd_reply = 0; 219186301Smav#endif 220186301Smavstatic int delayed_next_scr; 221186301Smav#if 0 /* SOS */ 222162922Sariffstatic char saved_console = -1; /* saved console number */ 223162922Sariff#endif 224165466Sariffstatic int configuration = 0; /* current setup */ 225165466Sariffstatic long scrn_blank_time = 0; /* screen saver timeout value */ 226165466Sariffstatic int scrn_blanked = 0; /* screen saver active flag */ 227162922Sariffstatic int scrn_saver = 0; /* screen saver routine */ 228162922Sariffstatic long scrn_time_stamp; 229162922Sariffstatic u_char scr_map[256]; 230162922Sariffstatic char *video_mode_ptr = NULL; 231162922Sariff 232165281Sariff/* function prototypes */ 233166294Sariffint pcprobe(struct isa_device *dev); 234169277Sariffint pcattach(struct isa_device *dev); 235169277Sariffint pcopen(dev_t dev, int flag, int mode, struct proc *p); 236174579Sariffint pcclose(dev_t dev, int flag, int mode, struct proc *p); 237172811Sariffint pcread(dev_t dev, struct uio *uio, int flag); 238162922Sariffint pcwrite(dev_t dev, struct uio *uio, int flag); 239165281Sariffint pcparam(struct tty *tp, struct termios *t); 240165281Sariffint pcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p); 241162922Sariffvoid pcxint(dev_t dev); 242162922Sariffvoid pcstart(struct tty *tp); 243162922Sariffvoid pccnprobe(struct consdev *cp); 244180532Sdelphijvoid pccninit(struct consdev *cp); 245162922Sariffvoid pccnputc(dev_t dev, char c); 246184483Smavint pccngetc(dev_t dev); 247178155Sariffint pccncheckc(dev_t dev); 248162922Sariffvoid scintr(int unit); 249169277Sariffint pcmmap(dev_t dev, int offset, int nprot); 250169277Sariffint getchar(void); 251162922Sariffstatic void scinit(void); 252162922Sariffstatic void scput(u_char c); 253162922Sariffstatic u_int scgetc(int noblock); 254162922Sariffstatic struct tty *get_tty_ptr(dev_t dev); 255162922Sariffstatic scr_stat *get_scr_stat(dev_t dev); 256162922Sariffstatic scr_stat *alloc_scp(); 257162922Sariffstatic void init_scp(scr_stat *scp); 258162922Sariffstatic int get_scr_num(); 259162922Sariffstatic void cursor_shape(int start, int end); 260165992Sariffstatic void get_cursor_shape(int *start, int *end); 261173817Sariffstatic void scrn_timer(); 262174182Sariffstatic void clear_screen(scr_stat *scp); 263182854Sjoelstatic int switch_scr(scr_stat *scp, u_int next_scr); 264169277Sariffstatic void exchange_scr(void); 265182999Smavstatic void move_crsr(scr_stat *scp, int x, int y); 266189879Smavstatic void scan_esc(scr_stat *scp, u_char c); 267162922Sariffstatic void undraw_cursor(scr_stat *scp); 268162922Sariffstatic void draw_cursor(scr_stat *scp); 269162965Sariffstatic void ansi_put(scr_stat *scp, u_char c); 270162965Sariffstatic u_char *get_fstr(u_int c, u_int *len); 271178155Sariffstatic void update_leds(int which); 272163276Sariffstatic void kbd_wait(void); 273178155Sariffstatic void kbd_cmd(u_char command); 274165281Sariffstatic void set_mode(scr_stat *scp); 275178155Sariffstatic void set_border(int color); 276178155Sariffstatic void set_vgaregs(char *modetable); 277167623Sariffstatic void copy_font(int direction, int segment, int size, char* font); 278169277Sariffstatic void save_palette(void); 279178155Sariffstatic void load_palette(void); 280190630Smavstatic void do_bell(scr_stat *scp, int pitch, int duration); 281178155Sariffstatic void blink_screen(scr_stat *scp); 282178155Sariff 283170518Sariff/* available screen savers */ 284178155Sariffstatic void none_saver(int test); 285169277Sariffstatic void blank_saver(int test); 286171141Sariffstatic void fade_saver(int test); 287162965Sariffstatic void star_saver(int test); 288162922Sariffstatic void snake_saver(int test); 289163257Sariffstatic void green_saver(int test); 290163257Sariff 291163257Sariffstatic const struct { 292163257Sariff char *name; 293162965Sariff void (*routine)(); 294164614Sariff} screen_savers[] = { 295164657Sariff { "none", none_saver }, /* 0 */ 296164657Sariff { "blank", blank_saver }, /* 1 */ 297182854Sjoel { "fade", fade_saver }, /* 2 */ 298172811Sariff { "star", star_saver }, /* 3 */ 299164657Sariff { "snake", snake_saver }, /* 4 */ 300163257Sariff { "green", green_saver }, /* 5 */ 301164657Sariff}; 302164657Sariff#define SCRN_SAVER(arg) (*screen_savers[scrn_saver].routine)(arg) 303164657Sariff#define NUM_SCRN_SAVERS (sizeof(screen_savers) / sizeof(screen_savers[0])) 304164657Sariff 305164614Sariff/* OS specific stuff */ 306164750Sariff#if 0 307164750Sariff#define VIRTUAL_TTY(x) (pccons[x] = ttymalloc(pccons[x])) 308164750Sariffstruct tty *pccons[MAXCONS]; 309164750Sariff#else 310164750Sariff#define VIRTUAL_TTY(x) &pccons[x] 311173817Sariffstruct tty pccons[MAXCONS]; 312173817Sariffint npccons = MAXCONS; 313173817Sariff#endif 314173817Sariff#define MONO_BUF pa_to_va(0xB0000) 315182999Smav#define CGA_BUF pa_to_va(0xB8000) 316182999Smavu_short *Crtat = (u_short *)MONO_BUF; 317182999Smav/*void consinit(void) {scinit();} SOS */ 318182999Smav 319182999Smavstruct isa_driver scdriver = { 320164828Sariff pcprobe, pcattach, "sc", 1 321164828Sariff}; 322164828Sariff 323164828Sariffint 324164828Sariffpcprobe(struct isa_device *dev) 325164828Sariff{ 326199846Smav int i, retries = 5; 327164828Sariff unsigned char val; 328165281Sariff 329165281Sariff /* Enable interrupts and keyboard controller */ 330165281Sariff kbd_wait(); 331165281Sariff outb(KB_STAT, KB_WRITE); 332165281Sariff kbd_wait(); 333165351Sariff outb(KB_DATA, KB_MODE); 334165351Sariff 335165351Sariff /* flush any noise in the buffer */ 336172811Sariff while (inb(KB_STAT) & KB_BUF_FULL) { 337165351Sariff DELAY(10); 338165351Sariff (void) inb(KB_DATA); 339172811Sariff } 340172811Sariff 341172811Sariff /* Reset keyboard hardware */ 342182854Sjoel while (retries--) { 343172811Sariff kbd_wait(); 344172811Sariff outb(KB_DATA, KB_RESET); 345165770Sariff for (i=0; i<100000; i++) { 346165770Sariff DELAY(10); 347165770Sariff val = inb(KB_DATA); 348173817Sariff if (val == KB_ACK || val == KB_ECHO) 349165770Sariff goto gotres; 350165770Sariff if (val == KB_RESEND) 351165992Sariff break; 352165992Sariff } 353165992Sariff } 354172811Sariffgotres: 355165992Sariff if (!retries) 356165992Sariff printf("scprobe: keyboard won't accept RESET command\n"); 357172811Sariff else { 358172811Sariffgotack: 359172811Sariff DELAY(10); 360172811Sariff while ((inb(KB_STAT) & KB_BUF_FULL) == 0) DELAY(10); 361172811Sariff DELAY(10); 362169277Sariff val = inb(KB_DATA); 363169277Sariff if (val == KB_ACK) 364169277Sariff goto gotack; 365170944Sariff if (val != KB_RESET_DONE) 366169277Sariff printf("scprobe: keyboard RESET failed %02x\n", val); 367169277Sariff } 368162922Sariff#ifdef XT_KEYBOARD 369182999Smav kbd_wait(); 370162922Sariff outb(KB_DATA, 0xF0); 371162922Sariff kbd_wait(); 372162922Sariff outb(KB_DATA, 1) 373162922Sariff kbd_wait(); 374162922Sariff#endif /* XT_KEYBOARD */ 375162922Sariff return (IO_KBDSIZE); 376162922Sariff} 377162922Sariff 378162922Sariffstatic struct kern_devconf kdc_sc[NSC] = { { 379182999Smav 0, 0, 0, /* filled in by dev_attach */ 380162922Sariff "sc", 0, { MDDT_ISA, 0, "tty" }, 381182999Smav isa_generic_externalize, 0, 0, ISA_EXTERNALLEN, 382182999Smav &kdc_isa0, /* parent */ 383169277Sariff 0, /* parentdata */ 384169277Sariff DC_UNKNOWN, /* not supported */ 385169277Sariff "Graphics console" 386163057Sariff} }; 387163057Sariff 388163057Sariffstatic inline void 389169277Sariffsc_registerdev(struct isa_device *id) 390169277Sariff{ 391169277Sariff if(id->id_unit) 392169277Sariff kdc_sc[id->id_unit] = kdc_sc[0]; 393169277Sariff kdc_sc[id->id_unit].kdc_unit = id->id_unit; 394169277Sariff kdc_sc[id->id_unit].kdc_isa = id; 395162922Sariff dev_attach(&kdc_sc[id->id_unit]); 396169277Sariff} 397169277Sariff 398169277Sariff 399169277Sariffint 400169277Sariffpcattach(struct isa_device *dev) 401169277Sariff{ 402182999Smav if (crtat == 0) 403169277Sariff scinit(); 404169277Sariff 405169277Sariff configuration = dev->id_flags; 406169277Sariff printf("sc%d: ", dev->id_unit); 407169277Sariff if (crtc_vga) 408169277Sariff if (crtc_addr == MONO_BASE) 409169277Sariff printf("VGA mono"); 410169277Sariff else 411169277Sariff printf("VGA color"); 412169277Sariff else 413169277Sariff if (crtc_addr == MONO_BASE) 414169277Sariff printf("MDA/hercules"); 415169277Sariff else 416169277Sariff printf("CGA/EGA"); 417169277Sariff if (MAXCONS > 1) 418171141Sariff printf(" <%d virtual consoles, flags=%x>\n", 419171141Sariff MAXCONS, configuration); 420171141Sariff else 421171141Sariff printf("\n"); 422163057Sariff console[0]->scr_buf = 423163057Sariff (u_short *)malloc(console[0]->xsize * console[0]->ysize * 424163057Sariff sizeof(u_short), M_DEVBUF, M_NOWAIT); 425163057Sariff if (crtc_vga) { 426163057Sariff#if defined(HARDFONTS) 427163057Sariff font_8 = font_8x8; 428163057Sariff font_14 = font_8x14; 429169277Sariff font_16 = font_8x16; 430169277Sariff fonts_loaded = FONT_8_LOADED|FONT_14_LOADED|FONT_16_LOADED; 431169277Sariff copy_font(LOAD, 1, 8, font_8); 432169277Sariff copy_font(LOAD, 2, 14, font_14); 433169277Sariff copy_font(LOAD, 0, 16, font_16); 434165039Sariff#else 435163057Sariff font_8 = (char *)malloc(8*256, M_DEVBUF, M_NOWAIT); 436163057Sariff font_14 = (char *)malloc(14*256, M_DEVBUF, M_NOWAIT); 437163136Sariff font_16 = (char *)malloc(16*256, M_DEVBUF, M_NOWAIT); 438163276Sariff copy_font(SAVE, 0, 16, font_16); 439169277Sariff fonts_loaded = FONT_16_LOADED; 440182999Smav#endif 441169277Sariff save_palette(); 442169277Sariff } 443169277Sariff /* get screensaver going */ 444169277Sariff scrn_timer(); 445169277Sariff update_leds(console[0]->status); 446169277Sariff sc_registerdev(dev); 447169277Sariff return 0; 448169277Sariff} 449165069Sariff 450163057Sariffstatic struct tty 451163057Sariff*get_tty_ptr(dev_t dev) 452163057Sariff{ 453163057Sariff int unit = minor(dev); 454162922Sariff 455162922Sariff if (unit > MAXCONS) 456162922Sariff return(NULL); 457162922Sariff return(VIRTUAL_TTY(unit)); 458169277Sariff} 459167648Sariff 460167648Sariffstatic scr_stat 461162922Sariff*get_scr_stat(dev_t dev) 462162922Sariff{ 463162922Sariff int unit = minor(dev); 464162922Sariff 465162922Sariff if (unit > MAXCONS) 466162922Sariff return(NULL); 467169277Sariff return(console[unit]); 468162922Sariff} 469165239Sariff 470162922Sariffstatic int 471182999Smavget_scr_num() 472182999Smav{ 473182999Smav int i = 0; 474162922Sariff 475182999Smav while ((i < MAXCONS) && (cur_console != console[i])) i++; 476182999Smav return i < MAXCONS ? i : 0; 477182999Smav} 478182999Smav 479182999Smavint 480182999Smavpcopen(dev_t dev, int flag, int mode, struct proc *p) 481162922Sariff{ 482162922Sariff struct tty *tp = get_tty_ptr(dev); 483193640Sariff 484162922Sariff if (!tp) 485162922Sariff return(ENXIO); 486162922Sariff 487162922Sariff tp->t_oproc = pcstart; 488162922Sariff tp->t_param = pcparam; 489189086Smav tp->t_dev = dev; 490194861Smav if (!(tp->t_state & TS_ISOPEN)) { 491189086Smav ttychars(tp); 492162922Sariff tp->t_iflag = TTYDEF_IFLAG; 493162922Sariff tp->t_oflag = TTYDEF_OFLAG; 494162922Sariff tp->t_cflag = TTYDEF_CFLAG; 495189086Smav tp->t_lflag = TTYDEF_LFLAG; 496162922Sariff tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 497211910Sjfv pcparam(tp, &tp->t_termios); 498218149Sjfv ttsetwater(tp); 499221794Sjfv } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) 500189086Smav return(EBUSY); 501189086Smav tp->t_state |= TS_CARR_ON; 502189086Smav tp->t_cflag |= CLOCAL; 503189086Smav if (!console[minor(dev)]) 504189086Smav console[minor(dev)] = alloc_scp(); 505197017Smav return((*linesw[tp->t_line].l_open)(dev, tp)); 506197017Smav} 507218149Sjfv 508218149Sjfvint 509189086Smavpcclose(dev_t dev, int flag, int mode, struct proc *p) 510189086Smav{ 511195690Smav struct tty *tp = get_tty_ptr(dev); 512189086Smav struct scr_stat *scp; 513189086Smav 514189086Smav if (!tp) 515189086Smav return(ENXIO); 516189086Smav scp = get_scr_stat(tp->t_dev); 517189086Smav if (scp->status & SWITCH_WAIT_ACQ) 518189086Smav wakeup((caddr_t)&scp->smode); 519189086Smav scp->pid = 0; 520194861Smav scp->proc = NULL; 521194861Smav scp->smode.mode = VT_AUTO; 522194861Smav /* free scp SOS */ 523194861Smav (*linesw[tp->t_line].l_close)(tp, flag); 524189086Smav ttyclose(tp); 525189086Smav return(0); 526189086Smav} 527189086Smav 528197018Smavint 529197018Smavpcread(dev_t dev, struct uio *uio, int flag) 530197018Smav{ 531197018Smav struct tty *tp = get_tty_ptr(dev); 532189086Smav 533189086Smav if (!tp) 534189086Smav return(ENXIO); 535189086Smav return((*linesw[tp->t_line].l_read)(tp, uio, flag)); 536189086Smav} 537189086Smav 538189086Smavint 539189086Smavpcwrite(dev_t dev, struct uio *uio, int flag) 540189086Smav{ 541189086Smav struct tty *tp = get_tty_ptr(dev); 542189086Smav 543189086Smav if (!tp) 544189086Smav return(ENXIO); 545189086Smav return((*linesw[tp->t_line].l_write)(tp, uio, flag)); 546216766Syongari} 547189086Smav 548189086Smavvoid 549189086Smavscintr(int unit) 550162922Sariff{ 551162922Sariff static struct tty *cur_tty; 552162922Sariff int c, len; 553162922Sariff u_char *cp; 554163136Sariff 555163136Sariff /* make screensaver happy */ 556186301Smav scrn_time_stamp = time.tv_sec; 557162922Sariff if (scrn_blanked) 558162922Sariff SCRN_SAVER(0); 559162922Sariff 560162922Sariff c = scgetc(1); 561169277Sariff 562169277Sariff cur_tty = VIRTUAL_TTY(get_scr_num()); 563169277Sariff 564169277Sariff if (!(cur_tty->t_state & TS_ISOPEN) || polling) 565169277Sariff return; 566169277Sariff 567169277Sariff switch (c & 0xff00) { 568169277Sariff case 0x0000: /* normal key */ 569169277Sariff (*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty); 570169277Sariff break; 571169277Sariff case NOKEY: /* nothing there */ 572169277Sariff break; 573169277Sariff case FKEY: /* function key, return string */ 574162922Sariff if (cp = get_fstr((u_int)c, (u_int *)&len)) { 575162922Sariff while (len-- > 0) 576162922Sariff (*linesw[cur_tty->t_line].l_rint) 577162922Sariff (*cp++ & 0xFF, cur_tty); 578162922Sariff } 579162922Sariff break; 580162922Sariff case MKEY: /* meta is active, prepend ESC */ 581162922Sariff (*linesw[cur_tty->t_line].l_rint)(0x1b, cur_tty); 582162922Sariff (*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty); 583162922Sariff break; 584162922Sariff } 585162922Sariff} 586162922Sariff 587162922Sariffint 588162922Sariffpcparam(struct tty *tp, struct termios *t) 589162922Sariff{ 590162922Sariff int cflag = t->c_cflag; 591162922Sariff 592162922Sariff /* and copy to tty */ 593162922Sariff tp->t_ispeed = t->c_ispeed; 594162922Sariff tp->t_ospeed = t->c_ospeed; 595162922Sariff tp->t_cflag = cflag; 596162922Sariff return 0; 597162922Sariff} 598162922Sariff 599162922Sariffint 600162922Sariffpcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) 601162922Sariff{ 602162922Sariff int i, error; 603162922Sariff struct tty *tp; 604162922Sariff struct trapframe *fp; 605162922Sariff scr_stat *scp; 606162922Sariff 607162922Sariff tp = get_tty_ptr(dev); 608162922Sariff if (!tp) 609162922Sariff return ENXIO; 610162922Sariff scp = get_scr_stat(tp->t_dev); 611162922Sariff 612162922Sariff switch (cmd) { /* process console hardware related ioctl's */ 613162922Sariff 614162922Sariff case GIO_ATTR: /* get current attributes */ 615162922Sariff *(int*)data = scp->term.cur_attr; 616162922Sariff return 0; 617162922Sariff 618162922Sariff case GIO_COLOR: /* is this a color console ? */ 619162922Sariff if (crtc_addr == COLOR_BASE) 620162922Sariff *(int*)data = 1; 621162922Sariff else 622199846Smav *(int*)data = 0; 623199846Smav return 0; 624199846Smav 625199846Smav case CONS_CURRENT: /* get current adapter type */ 626200375Smav if (crtc_vga) 627199846Smav *(int*)data = KD_VGA; 628162922Sariff else 629162922Sariff if (crtc_addr == MONO_BASE) 630162922Sariff *(int*)data = KD_MONO; 631169277Sariff else 632183024Smav *(int*)data = KD_CGA; 633171330Sariff return 0; 634183024Smav 635205413Smav case CONS_GET: /* get current video mode */ 636183024Smav *(int*)data = scp->mode; 637205413Smav return 0; 638205413Smav 639170518Sariff case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */ 640183024Smav scrn_blank_time = *(int*)data; 641183025Smav return 0; 642205413Smav 643162922Sariff#define SAVER(p) ((ssaver_t *)(p)) 644169277Sariff case CONS_SSAVER: /* set screen saver */ 645162922Sariff if (SAVER(data)->num < 0 646163057Sariff || SAVER(data)->num >= NUM_SCRN_SAVERS) 647163057Sariff return EIO; 648169277Sariff SCRN_SAVER(0); 649197640Smav scrn_saver = SAVER(data)->num; 650165305Sariff scrn_blank_time = SAVER(data)->time; 651182999Smav return 0; 652205413Smav 653162922Sariff case CONS_GSAVER: /* get screen saver info */ 654162922Sariff if (SAVER(data)->num < 0) 655169277Sariff SAVER(data)->num = scrn_saver; 656169277Sariff else if (SAVER(data)->num >= NUM_SCRN_SAVERS) 657186403Smav return EIO; 658186403Smav SAVER(data)->time = scrn_blank_time; 659186403Smav strcpy(SAVER(data)->name, screen_savers[SAVER(data)->num].name); 660186403Smav return 0; 661186403Smav 662186403Smav case CONS_CURSORTYPE: /* set cursor type blink/noblink */ 663169277Sariff if (*data) 664169277Sariff configuration |= BLINK_CURSOR; 665174025Sariff else 666169277Sariff configuration &= ~BLINK_CURSOR; 667186403Smav return 0; 668169277Sariff 669170518Sariff case CONS_BELLTYPE: /* set bell type sound/visual */ 670186403Smav if (*data) 671186403Smav configuration |= VISUAL_BELL; 672169277Sariff else 673162922Sariff configuration &= ~VISUAL_BELL; 674162922Sariff return 0; 675162922Sariff 676162922Sariff case CONS_GETINFO: /* get current (virtual) console info */ 677162922Sariff { 678162922Sariff vid_info_t *ptr = (vid_info_t*)data; 679162922Sariff if (ptr->size == sizeof(struct vid_info)) { 680162922Sariff ptr->m_num = get_scr_num(); 681182999Smav ptr->mv_col = scp->xpos; 682182999Smav ptr->mv_row = scp->ypos; 683182999Smav ptr->mv_csz = scp->xsize; 684182999Smav ptr->mv_rsz = scp->ysize; 685182999Smav ptr->mv_norm.fore = (scp->term.std_attr & 0x0f00)>>8; 686182999Smav ptr->mv_norm.back = (scp->term.std_attr & 0xf000)>>12; 687182999Smav ptr->mv_rev.fore = (scp->term.rev_attr & 0x0f00)>>8; 688182999Smav ptr->mv_rev.back = (scp->term.rev_attr & 0xf000)>>12; 689183894Smav ptr->mv_grfc.fore = 0; /* not supported */ 690183894Smav ptr->mv_grfc.back = 0; /* not supported */ 691183894Smav ptr->mv_ovscan = scp->border; 692183894Smav ptr->mk_keylock = scp->status & LOCK_KEY_MASK; 693183894Smav return 0; 694183894Smav } 695183894Smav return EINVAL; 696182999Smav } 697183894Smav 698183894Smav case CONS_GETVERS: /* get version number */ 699183894Smav *(int*)data = 0x200; /* version 2.0 */ 700183894Smav return 0; 701183894Smav 702183894Smav case SW_VGA_C40x25: case SW_VGA_C80x25: /* VGA TEXT MODES */ 703183894Smav case SW_VGA_M80x25: 704183894Smav case SW_VGA_C80x30: case SW_VGA_M80x30: 705200375Smav case SW_VGA_C80x50: case SW_VGA_M80x50: 706182999Smav case SW_VGA_C80x60: case SW_VGA_M80x60: 707200375Smav case SW_B40x25: case SW_C40x25: 708162922Sariff case SW_B80x25: case SW_C80x25: 709182999Smav case SW_ENH_B40x25: case SW_ENH_C40x25: 710183894Smav case SW_ENH_B80x25: case SW_ENH_C80x25: 711162922Sariff case SW_ENH_B80x43: case SW_ENH_C80x43: 712162922Sariff 713183894Smav if (!crtc_vga || video_mode_ptr == NULL) 714183894Smav return ENXIO; 715183894Smav switch (cmd & 0xff) { 716183894Smav case M_VGA_C80x60: case M_VGA_M80x60: 717183894Smav if (!(fonts_loaded & FONT_8_LOADED)) 718183894Smav return EINVAL; 719183894Smav scp->xsize = 80; 720183894Smav scp->ysize = 60; 721183894Smav break; 722162922Sariff case M_VGA_C80x50: case M_VGA_M80x50: 723162922Sariff if (!(fonts_loaded & FONT_8_LOADED)) 724183894Smav return EINVAL; 725183894Smav scp->xsize = 80; 726183894Smav scp->ysize = 50; 727183894Smav break; 728183894Smav case M_ENH_B80x43: case M_ENH_C80x43: 729183894Smav if (!(fonts_loaded & FONT_8_LOADED)) 730183894Smav return EINVAL; 731183894Smav scp->xsize = 80; 732183894Smav scp->ysize = 43; 733183894Smav break; 734183894Smav case M_VGA_C80x30: case M_VGA_M80x30: 735183894Smav scp->xsize = 80; 736183894Smav scp->ysize = 30; 737183894Smav break; 738183894Smav default: 739183894Smav if ((cmd & 0xff) > M_VGA_CG320) 740182999Smav return EINVAL; 741182999Smav else 742187020Smav scp->xsize = *(video_mode_ptr+((cmd&0xff)*64)); 743186146Smav scp->ysize = *(video_mode_ptr+((cmd&0xff)*64)+1)+1; 744182999Smav break; 745182999Smav } 746182999Smav scp->mode = cmd & 0xff; 747182999Smav scp->status &= ~UNKNOWN_MODE; /* text mode */ 748182999Smav free(scp->scr_buf, M_DEVBUF); 749182999Smav scp->scr_buf = (u_short *)malloc(scp->xsize * scp->ysize * 750186430Smav sizeof(u_short), M_DEVBUF, M_NOWAIT); 751162922Sariff if (scp == cur_console) 752186430Smav set_mode(scp); 753186430Smav else 754186430Smav scp->crt_base = scp->scr_buf; 755200375Smav clear_screen(scp); 756205413Smav if (tp->t_winsize.ws_col != scp->xsize 757223058Smav || tp->t_winsize.ws_row != scp->ysize) { 758208934Smav tp->t_winsize.ws_col = scp->xsize; 759223058Smav tp->t_winsize.ws_row = scp->ysize; 760223058Smav pgsignal(tp->t_pgrp, SIGWINCH, 1); 761223058Smav } 762223058Smav return 0; 763223058Smav 764223058Smav /* GRAPHICS MODES */ 765223058Smav case SW_BG320: case SW_CG320: case SW_BG640: 766223058Smav case SW_CG320_D: case SW_CG640_E: 767223058Smav case SW_CG640x350: case SW_ENH_CG640: 768162922Sariff case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320: 769162922Sariff 770169277Sariff if (!crtc_vga || video_mode_ptr == NULL) 771169277Sariff return ENXIO; 772169277Sariff scp->mode = cmd & 0xFF; 773169277Sariff scp->status |= UNKNOWN_MODE; /* graphics mode */ 774169277Sariff scp->xsize = (*(video_mode_ptr + (scp->mode*64))) * 8; 775169277Sariff scp->ysize = (*(video_mode_ptr + (scp->mode*64) + 1) + 1) 776169277Sariff * (*(video_mode_ptr + (scp->mode*64) + 2)); 777169277Sariff set_mode(scp); 778169277Sariff /* clear_graphics();*/ 779169277Sariff 780169277Sariff if (tp->t_winsize.ws_xpixel != scp->xsize 781169277Sariff || tp->t_winsize.ws_ypixel != scp->ysize) { 782169277Sariff tp->t_winsize.ws_xpixel = scp->xsize; 783186145Smav tp->t_winsize.ws_ypixel = scp->ysize; 784186145Smav pgsignal(tp->t_pgrp, SIGWINCH, 1); 785186145Smav } 786186145Smav return 0; 787186145Smav 788186145Smav case VT_SETMODE: /* set screen switcher mode */ 789186145Smav bcopy(data, &scp->smode, sizeof(struct vt_mode)); 790186145Smav if (scp->smode.mode == VT_PROCESS) { 791187020Smav scp->proc = p; 792187020Smav scp->pid = scp->proc->p_pid; 793187020Smav } 794187020Smav return 0; 795187020Smav 796187020Smav case VT_GETMODE: /* get screen switcher mode */ 797187020Smav bcopy(&scp->smode, data, sizeof(struct vt_mode)); 798187020Smav return 0; 799187020Smav 800187020Smav case VT_RELDISP: /* screen switcher ioctl */ 801187020Smav switch(*data) { 802187020Smav case VT_FALSE: /* user refuses to release screen, abort */ 803187020Smav if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) { 804187020Smav old_scp->status &= ~SWITCH_WAIT_REL; 805187020Smav switch_in_progress = 0; 806187020Smav return 0; 807199258Smav } 808199258Smav return EINVAL; 809199258Smav 810199258Smav case VT_TRUE: /* user has released screen, go on */ 811199258Smav if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) { 812199258Smav scp->status &= ~SWITCH_WAIT_REL; 813199258Smav exchange_scr(); 814199258Smav if (new_scp->smode.mode == VT_PROCESS) { 815199258Smav new_scp->status |= SWITCH_WAIT_ACQ; 816199258Smav psignal(new_scp->proc, 817169277Sariff new_scp->smode.acqsig); 818162922Sariff } 819182999Smav else 820186146Smav switch_in_progress = 0; 821186146Smav return 0; 822186146Smav } 823186146Smav return EINVAL; 824182999Smav 825169277Sariff case VT_ACKACQ: /* acquire acknowledged, switch completed */ 826182999Smav if (scp == new_scp && (scp->status & SWITCH_WAIT_ACQ)) { 827187020Smav scp->status &= ~SWITCH_WAIT_ACQ; 828187445Smav switch_in_progress = 0; 829187020Smav return 0; 830208934Smav } 831208934Smav return EINVAL; 832208934Smav 833208934Smav default: 834187020Smav return EINVAL; 835187445Smav } 836182999Smav /* NOT REACHED */ 837182999Smav 838183894Smav case VT_OPENQRY: /* return free virtual console */ 839222298Smav for (i = 0; i < MAXCONS; i++) { 840222298Smav tp = VIRTUAL_TTY(i); 841222298Smav if (!(tp->t_state & TS_ISOPEN)) { 842222298Smav *data = i + 1; 843222298Smav return 0; 844222298Smav } 845222298Smav } 846183894Smav return EINVAL; 847183894Smav 848162922Sariff case VT_ACTIVATE: /* switch to screen *data */ 849162922Sariff return switch_scr(scp, (*data) - 1); 850162922Sariff 851162922Sariff case VT_WAITACTIVE: /* wait for switch to occur */ 852162922Sariff if (*data > MAXCONS || *data < 0) 853199846Smav return EINVAL; 854199846Smav if (minor(dev) == (*data) - 1) 855162922Sariff return 0; 856169277Sariff if (*data == 0) { 857183024Smav if (scp == cur_console) 858171330Sariff return 0; 859183024Smav } 860205413Smav else 861183024Smav scp = console[(*data) - 1]; 862205413Smav while ((error=tsleep((caddr_t)&scp->smode, PZERO|PCATCH, 863205413Smav "waitvt", 0)) == ERESTART) ; 864170518Sariff return error; 865183024Smav 866183024Smav case VT_GETACTIVE: 867205413Smav *data = get_scr_num()+1; 868162922Sariff return 0; 869169277Sariff 870162922Sariff case KDENABIO: /* allow io operations */ 871162922Sariff fp = (struct trapframe *)p->p_md.md_regs; 872163057Sariff fp->tf_eflags |= PSL_IOPL; 873169277Sariff return 0; 874197640Smav 875165305Sariff case KDDISABIO: /* disallow io operations (default) */ 876182999Smav fp = (struct trapframe *)p->p_md.md_regs; 877205413Smav fp->tf_eflags &= ~PSL_IOPL; 878186403Smav return 0; 879186403Smav 880186403Smav case KDSETMODE: /* set current mode of this (virtual) console */ 881186403Smav switch (*data) { 882186403Smav case KD_TEXT: /* switch to TEXT (known) mode */ 883169277Sariff /* restore fonts & palette ! */ 884169277Sariff if (crtc_vga) { 885174025Sariff if (fonts_loaded & FONT_16_LOADED) 886186403Smav copy_font(LOAD, 0, 16, font_16); 887186403Smav if (fonts_loaded & FONT_8_LOADED) 888169277Sariff copy_font(LOAD, 1, 8, font_8); 889186403Smav if (fonts_loaded & FONT_14_LOADED) 890186403Smav copy_font(LOAD, 2, 14, font_14); 891170518Sariff load_palette(); 892186403Smav } 893162922Sariff /* FALL THROUGH */ 894200375Smav 895200375Smav case KD_TEXT1: /* switch to TEXT (known) mode */ 896183894Smav /* no restore fonts & palette */ 897183894Smav scp->status &= ~UNKNOWN_MODE; 898183894Smav if (crtc_vga && video_mode_ptr) 899183894Smav set_mode(scp); 900183894Smav clear_screen(scp); 901183894Smav return 0; 902183894Smav 903183894Smav case KD_GRAPHICS:/* switch to GRAPHICS (unknown) mode */ 904162922Sariff scp->status |= UNKNOWN_MODE; 905183894Smav return 0; 906162922Sariff default: 907162922Sariff return EINVAL; 908183894Smav } 909183894Smav /* NOT REACHED */ 910183894Smav 911183894Smav case KDGETMODE: /* get current mode of this (virtual) console */ 912183894Smav *data = (scp->status & UNKNOWN_MODE) ? KD_GRAPHICS : KD_TEXT; 913183894Smav return 0; 914182999Smav 915182999Smav case KDSBORDER: /* set border color of this (virtual) console */ 916183894Smav if (!crtc_vga) 917183894Smav return ENXIO; 918183894Smav scp->border = *data; 919166796Sariff if (scp == cur_console) 920183894Smav set_border(scp->border); 921183894Smav return 0; 922183894Smav 923183894Smav case KDSKBSTATE: /* set keyboard state (locks) */ 924183894Smav if (*data >= 0 && *data <= LOCK_KEY_MASK) { 925183894Smav scp->status &= ~LOCK_KEY_MASK; 926183894Smav scp->status |= *data; 927183894Smav if (scp == cur_console) 928183894Smav update_leds(scp->status); 929183894Smav return 0; 930183894Smav } 931183894Smav return EINVAL; 932183894Smav 933183894Smav case KDGKBSTATE: /* get keyboard state (locks) */ 934183894Smav *data = scp->status & LOCK_KEY_MASK; 935183894Smav return 0; 936183894Smav 937183894Smav case KDSETRAD: /* set keyboard repeat & delay rates */ 938183894Smav if (*data & 0x80) 939183894Smav return EINVAL; 940183894Smav i = spltty(); 941183894Smav kbd_cmd(KB_SETRAD); 942183894Smav kbd_cmd(*data); 943183894Smav splx(i); 944183894Smav return 0; 945183894Smav 946183894Smav case KDSKBMODE: /* set keyboard mode */ 947186430Smav switch (*data) { 948186430Smav case K_RAW: /* switch to RAW scancode mode */ 949186430Smav scp->status |= KBD_RAW_MODE; 950200375Smav return 0; 951205413Smav 952223058Smav case K_XLATE: /* switch to XLT ascii mode */ 953208934Smav if (scp == cur_console && scp->status == KBD_RAW_MODE) 954223058Smav shfts = ctls = alts = agrs = metas = 0; 955223058Smav scp->status &= ~KBD_RAW_MODE; 956223058Smav return 0; 957223058Smav default: 958223058Smav return EINVAL; 959223058Smav } 960223058Smav /* NOT REACHED */ 961223058Smav 962223058Smav case KDGKBMODE: /* get keyboard mode */ 963169277Sariff *data = (scp->status & KBD_RAW_MODE) ? K_RAW : K_XLATE; 964169277Sariff return 0; 965169277Sariff 966169277Sariff case KDMKTONE: /* sound the bell */ 967169277Sariff if (*(int*)data) { 968169277Sariff do_bell(scp, (*(int*)data)&0xffff, 969169277Sariff (((*(int*)data)>>16)&0xffff)*hz/1000); 970169277Sariff } 971169277Sariff else 972169277Sariff do_bell(scp, scp->bell_pitch, scp->bell_duration); 973169277Sariff return 0; 974169277Sariff 975186145Smav case KIOCSOUND: /* make tone (*data) hz */ 976186145Smav if (scp == cur_console) { 977186145Smav if (*(int*)data) { 978186145Smav int pitch = TIMER_FREQ/(*(int*)data); 979186145Smav /* set command for counter 2, 2 byte write */ 980186145Smav if (acquire_timer2(TIMER_16BIT|TIMER_SQWAVE)) { 981186145Smav return EBUSY; 982186145Smav } 983187020Smav /* set pitch */ 984187020Smav outb(TIMER_CNTR2, pitch); 985187020Smav outb(TIMER_CNTR2, (pitch>>8)); 986187020Smav /* enable counter 2 output to speaker */ 987187020Smav outb(IO_PPI, inb(IO_PPI) | 3); 988187020Smav } 989187020Smav else { 990187020Smav /* disable counter 2 output to speaker */ 991187020Smav outb(IO_PPI, inb(IO_PPI) & 0xFC); 992187020Smav release_timer2(); 993187020Smav } 994187020Smav } 995187020Smav return 0; 996187020Smav 997187020Smav case KDGKBTYPE: /* get keyboard type */ 998187020Smav *data = 0; /* type not known (yet) */ 999199258Smav return 0; 1000199258Smav 1001199258Smav case KDSETLED: /* set keyboard LED status */ 1002199258Smav if (*data >= 0 && *data <= LED_MASK) { 1003199258Smav scp->status &= ~LED_MASK; 1004199258Smav scp->status |= *data; 1005199258Smav if (scp == cur_console) 1006199258Smav update_leds(scp->status); 1007199258Smav return 0; 1008199258Smav } 1009186146Smav return EINVAL; 1010186146Smav 1011186146Smav case KDGETLED: /* get keyboard LED status */ 1012186146Smav *data = scp->status & LED_MASK; 1013187020Smav return 0; 1014187445Smav 1015187020Smav case GETFKEY: /* get functionkey string */ 1016187445Smav if (*(u_short*)data < n_fkey_tab) { 1017187020Smav fkeyarg_t *ptr = (fkeyarg_t*)data; 1018208934Smav bcopy(&fkey_tab[ptr->keynum].str, 1019208934Smav ptr->keydef, 1020208934Smav fkey_tab[ptr->keynum].len); 1021208934Smav ptr->flen = fkey_tab[ptr->keynum].len; 1022222298Smav return 0; 1023222298Smav } 1024222298Smav else 1025222298Smav return EINVAL; 1026222298Smav 1027222298Smav case SETFKEY: /* set functionkey string */ 1028222298Smav if (*(u_short*)data < n_fkey_tab) { 1029187020Smav fkeyarg_t *ptr = (fkeyarg_t*)data; 1030186146Smav bcopy(ptr->keydef, 1031162922Sariff &fkey_tab[ptr->keynum].str, 1032162922Sariff min(ptr->flen, MAXFK)); 1033169277Sariff fkey_tab[ptr->keynum].len = min(ptr->flen, MAXFK); 1034200375Smav return 0; 1035162922Sariff } 1036162922Sariff else 1037182999Smav return EINVAL; 1038182999Smav 1039162922Sariff case GIO_SCRNMAP: /* get output translation table */ 1040169277Sariff bcopy(&scr_map, data, sizeof(scr_map)); 1041182999Smav return 0; 1042182999Smav 1043183894Smav case PIO_SCRNMAP: /* set output translation table */ 1044183894Smav bcopy(data, &scr_map, sizeof(scr_map)); 1045162922Sariff return 0; 1046162922Sariff 1047162922Sariff case GIO_KEYMAP: /* get keyboard translation table */ 1048162922Sariff bcopy(&key_map, data, sizeof(key_map)); 1049162922Sariff return 0; 1050162922Sariff 1051162922Sariff case PIO_KEYMAP: /* set keyboard translation table */ 1052162922Sariff bcopy(data, &key_map, sizeof(key_map)); 1053182999Smav return 0; 1054162922Sariff 1055162922Sariff case PIO_FONT8x8: /* set 8x8 dot font */ 1056162922Sariff if (!crtc_vga) 1057162922Sariff return ENXIO; 1058169277Sariff bcopy(data, font_8, 8*256); 1059162922Sariff fonts_loaded |= FONT_8_LOADED; 1060162922Sariff copy_font(LOAD, 1, 8, font_8); 1061162922Sariff return 0; 1062162922Sariff 1063162922Sariff case GIO_FONT8x8: /* get 8x8 dot font */ 1064162922Sariff if (!crtc_vga) 1065162922Sariff return ENXIO; 1066162922Sariff if (fonts_loaded & FONT_8_LOADED) { 1067182999Smav bcopy(font_8, data, 8*256); 1068182999Smav return 0; 1069182999Smav } 1070182999Smav else 1071162922Sariff return ENXIO; 1072162922Sariff 1073162922Sariff case PIO_FONT8x14: /* set 8x14 dot font */ 1074162922Sariff if (!crtc_vga) 1075162922Sariff return ENXIO; 1076162922Sariff bcopy(data, font_14, 14*256); 1077162922Sariff fonts_loaded |= FONT_14_LOADED; 1078162922Sariff copy_font(LOAD, 2, 14, font_14); 1079162922Sariff return 0; 1080162922Sariff 1081162922Sariff case GIO_FONT8x14: /* get 8x14 dot font */ 1082182999Smav if (!crtc_vga) 1083182999Smav return ENXIO; 1084162922Sariff if (fonts_loaded & FONT_14_LOADED) { 1085162922Sariff bcopy(font_14, data, 14*256); 1086162922Sariff return 0; 1087162922Sariff } 1088182999Smav else 1089162922Sariff return ENXIO; 1090162922Sariff 1091162922Sariff case PIO_FONT8x16: /* set 8x16 dot font */ 1092162922Sariff if (!crtc_vga) 1093164614Sariff return ENXIO; 1094164614Sariff bcopy(data, font_16, 16*256); 1095164614Sariff fonts_loaded |= FONT_16_LOADED; 1096182999Smav copy_font(LOAD, 0, 16, font_16); 1097182999Smav return 0; 1098162922Sariff 1099162922Sariff case GIO_FONT8x16: /* get 8x16 dot font */ 1100162922Sariff if (!crtc_vga) 1101182999Smav return ENXIO; 1102182999Smav if (fonts_loaded & FONT_16_LOADED) { 1103182999Smav bcopy(font_16, data, 16*256); 1104182999Smav return 0; 1105162922Sariff } 1106162922Sariff else 1107182999Smav return ENXIO; 1108162922Sariff#if 0 /* this should really go away !! */ 1109162922Sariff case CONSOLE_X_MODE_ON: /* just to be compatible */ 1110162922Sariff if (saved_console < 0) { 1111162922Sariff saved_console = get_scr_num(); 1112182999Smav switch_scr(scp, minor(dev)); 1113162922Sariff fp = (struct trapframe *)p->p_md.md_regs; 1114162922Sariff fp->tf_eflags |= PSL_IOPL; 1115163257Sariff scp->status |= UNKNOWN_MODE; 1116162922Sariff scp->status |= KBD_RAW_MODE; 1117162922Sariff return 0; 1118162922Sariff } 1119162922Sariff return EAGAIN; 1120162922Sariff 1121162922Sariff case CONSOLE_X_MODE_OFF:/* just to be compatible */ 1122162922Sariff fp = (struct trapframe *)p->p_md.md_regs; 1123162922Sariff fp->tf_eflags &= ~PSL_IOPL; 1124162922Sariff if (crtc_vga) { 1125162922Sariff if (fonts_loaded & FONT_16_LOADED) 1126162922Sariff copy_font(LOAD, 0, 16, font_16); 1127162922Sariff if (fonts_loaded & FONT_8_LOADED) 1128162922Sariff copy_font(LOAD, 1, 8, font_8); 1129162922Sariff if (fonts_loaded & FONT_14_LOADED) 1130162922Sariff copy_font(LOAD, 2, 14, font_14); 1131162922Sariff load_palette(); 1132162922Sariff set_mode(scp); 1133162922Sariff } 1134162922Sariff scp->status &= ~UNKNOWN_MODE; 1135162922Sariff clear_screen(scp); 1136162922Sariff scp->status &= ~KBD_RAW_MODE; 1137182999Smav switch_scr(scp, saved_console); 1138162922Sariff saved_console = -1; 1139162922Sariff return 0; 1140162922Sariff 1141162922Sariff case CONSOLE_X_BELL: /* more compatibility */ 1142162922Sariff /* 1143162922Sariff * if set, data is a pointer to a length 2 array of 1144162922Sariff * integers. data[0] is the pitch in Hz and data[1] 1145162922Sariff * is the duration in msec. 1146162922Sariff */ 1147162922Sariff if (data) 1148162922Sariff do_bell(scp, TIMER_FREQ/((int*)data)[0], 1149162922Sariff ((int*)data)[1]*hz/1000); 1150162922Sariff else 1151162922Sariff do_bell(scp, scp->bell_pitch, scp->bell_duration); 1152162922Sariff return 0; 1153182999Smav#endif 1154162922Sariff default: 1155162922Sariff break; 1156182999Smav } 1157182999Smav 1158162922Sariff error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 1159162922Sariff if (error >= 0) 1160162922Sariff return(error); 1161162922Sariff error = ttioctl(tp, cmd, data, flag); 1162162922Sariff if (error >= 0) 1163162922Sariff return(error); 1164182999Smav return(ENOTTY); 1165162922Sariff} 1166182999Smav 1167162922Sariffvoid 1168182999Smavpcxint(dev_t dev) 1169182999Smav{ 1170182999Smav struct tty *tp = get_tty_ptr(dev); 1171182999Smav 1172182999Smav if (!tp) 1173162922Sariff return; 1174182999Smav tp->t_state &= ~TS_BUSY; 1175162922Sariff if (tp->t_line) 1176162922Sariff (*linesw[tp->t_line].l_start)(tp); 1177162922Sariff else 1178182999Smav pcstart(tp); 1179162922Sariff} 1180162922Sariff 1181182999Smavvoid 1182182999Smavpcstart(struct tty *tp) 1183182999Smav{ 1184162922Sariff struct clist *rbp; 1185162922Sariff int i, s, len; 1186162922Sariff u_char buf[PCBURST]; 1187182999Smav scr_stat *scp = get_scr_stat(tp->t_dev); 1188162922Sariff 1189162922Sariff if (scp->status & SLKED) 1190162922Sariff return; 1191182999Smav s = spltty(); 1192182999Smav if (!(tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) { 1193162922Sariff tp->t_state |= TS_BUSY; 1194162922Sariff splx(s); 1195162922Sariff rbp = &tp->t_outq; 1196162922Sariff scp->cursor_protect = 1; 1197162922Sariff undraw_cursor(scp); 1198162922Sariff while (rbp->c_cc) { 1199162922Sariff len = q_to_b(rbp, buf, PCBURST); 1200162922Sariff for (i=0; i<len; i++) 1201182999Smav if (buf[i]) ansi_put(scp, buf[i]); 1202182999Smav } 1203182999Smav draw_cursor(scp); 1204182999Smav scp->cursor_protect = 0; 1205182999Smav s = spltty(); 1206182999Smav tp->t_state &= ~TS_BUSY; 1207182999Smav#if 0 1208182999Smav if (rbp->c_cc) { 1209182999Smav tp->t_state |= TS_TIMEOUT; 1210162922Sariff timeout((timeout_func_t)ttrstrt, (caddr_t)tp, 1); 1211171141Sariff } 1212182999Smav#endif 1213171141Sariff if (rbp->c_cc <= tp->t_lowat) { 1214182999Smav if (tp->t_state & TS_ASLEEP) { 1215182999Smav tp->t_state &= ~TS_ASLEEP; 1216182999Smav wakeup((caddr_t)rbp); 1217182999Smav } 1218182999Smav selwakeup(&tp->t_wsel); 1219171141Sariff } 1220182999Smav } 1221182999Smav splx(s); 1222182999Smav} 1223162922Sariff 1224182999Smavvoid 1225162922Sariffpccnprobe(struct consdev *cp) 1226182999Smav{ 1227182999Smav int maj; 1228182999Smav 1229182999Smav /* locate the major number */ 1230182999Smav for (maj = 0; maj < nchrdev; maj++) 1231182999Smav if ((void*)cdevsw[maj].d_open == (void*)pcopen) 1232162922Sariff break; 1233182999Smav 1234182999Smav /* initialize required fields */ 1235162922Sariff cp->cn_dev = makedev(maj, 0); 1236182999Smav cp->cn_pri = CN_INTERNAL; 1237182999Smav} 1238182999Smav 1239163057Sariffvoid 1240163057Sariffpccninit(struct consdev *cp) 1241182999Smav{ 1242169277Sariff scinit(); 1243162922Sariff} 1244162922Sariff 1245169277Sariffvoid 1246162922Sariffpccnputc(dev_t dev, char c) 1247169277Sariff{ 1248169277Sariff if (c == '\n') 1249169277Sariff scput('\r'); 1250169277Sariff scput(c); 1251169277Sariff} 1252169277Sariff 1253162922Sariffint 1254182999Smavpccngetc(dev_t dev) 1255182999Smav{ 1256182999Smav int s = spltty(); /* block scintr while we poll */ 1257182999Smav int c = scgetc(0); 1258182999Smav splx(s); 1259182999Smav return(c); 1260182999Smav} 1261182999Smav 1262182999Smavint 1263182999Smavpccncheckc(dev_t dev) 1264182999Smav{ 1265169277Sariff return (scgetc(1) & 0xff); 1266182999Smav} 1267182999Smav 1268182999Smavstatic void 1269182999Smavnone_saver(int test) 1270182999Smav{ 1271162922Sariff} 1272182999Smav 1273182999Smavstatic void 1274163057Sarifffade_saver(int test) 1275163057Sariff{ 1276182999Smav static int count = 0; 1277182999Smav int i; 1278182999Smav 1279182999Smav if (test) { 1280182999Smav scrn_blanked = 1; 1281182999Smav if (count < 64) { 1282169277Sariff outb(PIXMASK, 0xFF); /* no pixelmask */ 1283169277Sariff outb(PALWADR, 0x00); 1284169277Sariff outb(PALDATA, 0); 1285169277Sariff outb(PALDATA, 0); 1286169277Sariff outb(PALDATA, 0); 1287169277Sariff for (i = 3; i < 768; i++) { 1288162922Sariff if (palette[i] - count > 15) 1289162922Sariff outb(PALDATA, palette[i]-count); 1290182999Smav else 1291182999Smav outb(PALDATA, 15); 1292182999Smav } 1293182999Smav inb(crtc_addr+6); /* reset flip/flop */ 1294182999Smav outb(ATC, 0x20); /* enable palette */ 1295182999Smav count++; 1296182999Smav } 1297182999Smav } 1298182999Smav else { 1299182999Smav count = scrn_blanked = 0; 1300182999Smav load_palette(); 1301182999Smav } 1302182999Smav} 1303182999Smav 1304182999Smavstatic void 1305182999Smavblank_saver(int test) 1306182999Smav{ 1307182999Smav u_char val; 1308182999Smav if (test) { 1309182999Smav scrn_blanked = 1; 1310182999Smav outb(TSIDX, 0x01); val = inb(TSREG); 1311182999Smav outb(TSIDX, 0x01); outb(TSREG, val | 0x20); 1312182999Smav } 1313182999Smav else { 1314182999Smav scrn_blanked = 0; 1315182999Smav outb(TSIDX, 0x01); val = inb(TSREG); 1316182999Smav outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); 1317182999Smav } 1318182999Smav} 1319182999Smav 1320182999Smavstatic void 1321182999Smavgreen_saver(int test) 1322182999Smav{ 1323182999Smav u_char val; 1324182999Smav if (test) { 1325182999Smav scrn_blanked = 1; 1326182999Smav outb(TSIDX, 0x01); val = inb(TSREG); 1327182999Smav outb(TSIDX, 0x01); outb(TSREG, val | 0x20); 1328182999Smav outb(crtc_addr, 0x17); val = inb(crtc_addr + 1); 1329182999Smav outb(crtc_addr + 1, val & ~0x80); 1330182999Smav } 1331182999Smav else { 1332182999Smav scrn_blanked = 0; 1333182999Smav outb(TSIDX, 0x01); val = inb(TSREG); 1334182999Smav outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); 1335182999Smav outb(crtc_addr, 0x17); val = inb(crtc_addr + 1); 1336182999Smav outb(crtc_addr + 1, val | 0x80); 1337182999Smav } 1338182999Smav} 1339182999Smav 1340182999Smav#define NUM_STARS 50 1341182999Smav 1342182999Smav/* 1343182999Smav * Alternate saver that got its inspiration from a well known utility 1344182999Smav * package for an inferior^H^H^H^H^H^Hfamous OS. 1345182999Smav */ 1346182999Smavstatic void 1347182999Smavstar_saver(int test) 1348182999Smav{ 1349169277Sariff scr_stat *scp = cur_console; 1350182999Smav int cell, i; 1351182999Smav char pattern[] = {"...........++++*** "}; 1352182999Smav char colors[] = {FG_DARKGREY, FG_LIGHTGREY, 1353182999Smav FG_WHITE, FG_LIGHTCYAN}; 1354182999Smav static u_short stars[NUM_STARS][2]; 1355182999Smav 1356169277Sariff if (test) { 1357182999Smav if (!scrn_blanked) { 1358182999Smav bcopyw(Crtat, scp->scr_buf, 1359182999Smav scp->xsize * scp->ysize * 2); 1360182999Smav fillw((FG_LIGHTGREY|BG_BLACK)<<8 | scr_map[0x20], Crtat, 1361182999Smav scp->xsize * scp->ysize); 1362182999Smav set_border(0); 1363182999Smav i = scp->ysize * scp->xsize + 5; 1364182999Smav outb(crtc_addr, 14); 1365182999Smav outb(crtc_addr+1, i >> 8); 1366182999Smav outb(crtc_addr, 15); 1367182999Smav outb(crtc_addr+1, i & 0xff); 1368169277Sariff scrn_blanked = 1; 1369162922Sariff for(i=0; i<NUM_STARS; i++) { 1370162922Sariff stars[i][0] = 1371162922Sariff random() % (scp->xsize*scp->ysize); 1372182999Smav stars[i][1] = 0; 1373182999Smav } 1374182999Smav } 1375162922Sariff cell = random() % NUM_STARS; 1376162922Sariff *((u_short*)(Crtat + stars[cell][0])) = 1377162922Sariff scr_map[pattern[stars[cell][1]]] | 1378162922Sariff colors[random()%sizeof(colors)] << 8; 1379162922Sariff if ((stars[cell][1]+=(random()%4)) >= sizeof(pattern)-1) { 1380182999Smav stars[cell][0] = random() % (scp->xsize*scp->ysize); 1381162922Sariff stars[cell][1] = 0; 1382162922Sariff } 1383162922Sariff } 1384162922Sariff else { 1385162922Sariff if (scrn_blanked) { 1386162922Sariff bcopyw(scp->scr_buf, Crtat, scp->xsize*scp->ysize*2); 1387163057Sariff set_border(scp->border); 1388182999Smav scrn_blanked = 0; 1389162922Sariff } 1390162922Sariff } 1391182999Smav} 1392182999Smav 1393182999Smavstatic void 1394182999Smavsnake_saver(int test) 1395162965Sariff{ 1396182999Smav const char saves[] = {"FreeBSD-2.0"}; 1397162922Sariff static u_char *savs[sizeof(saves)-1]; 1398162965Sariff static int dirx, diry; 1399162922Sariff int f; 1400162922Sariff scr_stat *scp = cur_console; 1401162922Sariff 1402162922Sariff if (test) { 1403162922Sariff if (!scrn_blanked) { 1404162922Sariff bcopyw(Crtat, scp->scr_buf, 1405162922Sariff scp->xsize * scp->ysize * 2); 1406162922Sariff fillw((FG_LIGHTGREY|BG_BLACK)<<8 | scr_map[0x20], 1407182999Smav Crtat, scp->xsize * scp->ysize); 1408162922Sariff set_border(0); 1409162922Sariff dirx = (scp->xpos ? 1 : -1); 1410162922Sariff diry = (scp->ypos ? 1411162922Sariff scp->xsize : -scp->xsize); 1412164614Sariff for (f=0; f< sizeof(saves)-1; f++) 1413162922Sariff savs[f] = (u_char *)Crtat + 2 * 1414162922Sariff (scp->xpos+scp->ypos*scp->xsize); 1415162922Sariff *(savs[0]) = scr_map[*saves]; 1416162922Sariff f = scp->ysize * scp->xsize + 5; 1417162922Sariff outb(crtc_addr, 14); 1418162922Sariff outb(crtc_addr+1, f >> 8); 1419162922Sariff outb(crtc_addr, 15); 1420171330Sariff outb(crtc_addr+1, f & 0xff); 1421164614Sariff scrn_blanked = 1; 1422162922Sariff } 1423162922Sariff if (scrn_blanked++ < 4) 1424162922Sariff return; 1425162922Sariff scrn_blanked = 1; 1426162922Sariff *(savs[sizeof(saves)-2]) = scr_map[0x20]; 1427162922Sariff for (f=sizeof(saves)-2; f > 0; f--) 1428162922Sariff savs[f] = savs[f-1]; 1429162922Sariff f = (savs[0] - (u_char *)Crtat) / 2; 1430163057Sariff if ((f % scp->xsize) == 0 || 1431163057Sariff (f % scp->xsize) == scp->xsize - 1 || 1432182999Smav (random() % 50) == 0) 1433163057Sariff dirx = -dirx; 1434163057Sariff if ((f / scp->xsize) == 0 || 1435163057Sariff (f / scp->xsize) == scp->ysize - 1 || 1436163057Sariff (random() % 20) == 0) 1437162922Sariff diry = -diry; 1438162922Sariff savs[0] += 2*dirx + 2*diry; 1439162922Sariff for (f=sizeof(saves)-2; f>=0; f--) 1440163057Sariff *(savs[f]) = scr_map[saves[f]]; 1441162922Sariff } 1442162922Sariff else { 1443162922Sariff if (scrn_blanked) { 1444162922Sariff bcopyw(scp->scr_buf, Crtat, 1445162922Sariff scp->xsize * scp->ysize * 2); 1446164614Sariff set_border(scp->border); 1447162922Sariff scrn_blanked = 0; 1448162922Sariff } 1449162922Sariff } 1450162922Sariff} 1451164614Sariff 1452164614Sariffstatic void 1453162922Sariffcursor_shape(int start, int end) 1454162922Sariff{ 1455162922Sariff outb(crtc_addr, 10); 1456162922Sariff outb(crtc_addr+1, start & 0xFF); 1457162922Sariff outb(crtc_addr, 11); 1458162922Sariff outb(crtc_addr+1, end & 0xFF); 1459162922Sariff} 1460162922Sariff 1461162922Sariff#if !defined(FAT_CURSOR) 1462162922Sariffstatic void 1463162922Sariffget_cursor_shape(int *start, int *end) 1464162922Sariff{ 1465162922Sariff outb(crtc_addr, 10); 1466164614Sariff *start = inb(crtc_addr+1) & 0x1F; 1467171141Sariff outb(crtc_addr, 11); 1468182999Smav *end = inb(crtc_addr+1) & 0x1F; 1469162922Sariff} 1470162922Sariff#endif 1471162922Sariff 1472162922Sariffstatic void 1473164614Sariffscrn_timer() 1474164614Sariff{ 1475164614Sariff timeout((timeout_func_t)scrn_timer, 0, hz/5); 1476164614Sariff if (cur_console->status & UNKNOWN_MODE) 1477171141Sariff return; 1478162922Sariff if (!cur_console->cursor_protect && configuration & BLINK_CURSOR) { 1479162922Sariff if (cur_console->cursor_saveunder) 1480163057Sariff undraw_cursor(cur_console); 1481162922Sariff else 1482162922Sariff draw_cursor(cur_console); 1483162922Sariff } 1484162922Sariff if (scrn_blank_time && (time.tv_sec > scrn_time_stamp+scrn_blank_time)) 1485171141Sariff SCRN_SAVER(1); 1486171141Sariff} 1487162922Sariff 1488163057Sariffstatic void 1489162922Sariffclear_screen(scr_stat *scp) 1490162922Sariff{ 1491162922Sariff move_crsr(scp, 0, 0); 1492163057Sariff fillw(scp->term.cur_attr | scr_map[0x20], scp->crt_base, 1493164614Sariff scp->xsize * scp->ysize); 1494164614Sariff} 1495171141Sariff 1496171141Sariffstatic int 1497162922Sariffswitch_scr(scr_stat *scp, u_int next_scr) 1498162922Sariff{ 1499162922Sariff if (switch_in_progress && 1500162922Sariff (cur_console->proc != pfind(cur_console->pid))) 1501162922Sariff switch_in_progress = 0; 1502162922Sariff 1503162922Sariff if (next_scr >= MAXCONS || switch_in_progress 1504162922Sariff || (cur_console->smode.mode == VT_AUTO 1505164614Sariff && cur_console->status & UNKNOWN_MODE)) { 1506163057Sariff do_bell(scp, BELL_PITCH, BELL_DURATION); 1507182999Smav return EINVAL; 1508182999Smav } 1509182999Smav 1510182999Smav /* is the wanted virtual console open ? */ 1511182999Smav if (next_scr) { 1512162922Sariff struct tty *tp = VIRTUAL_TTY(next_scr); 1513162922Sariff if (!(tp->t_state & TS_ISOPEN)) { 1514164614Sariff do_bell(scp, BELL_PITCH, BELL_DURATION); 1515164614Sariff return EINVAL; 1516162922Sariff } 1517162922Sariff } 1518162922Sariff /* delay switch if actively updating screen */ 1519164614Sariff if (write_in_progress || blink_in_progress) { 1520162922Sariff delayed_next_scr = next_scr+1; 1521182999Smav return 0; 1522182999Smav } 1523182999Smav switch_in_progress = 1; 1524182999Smav old_scp = cur_console; 1525171141Sariff new_scp = console[next_scr]; 1526171141Sariff wakeup((caddr_t)&new_scp->smode); 1527162922Sariff if (new_scp == old_scp) { 1528162922Sariff switch_in_progress = 0; 1529162922Sariff return 0; 1530182999Smav } 1531162922Sariff 1532162922Sariff /* has controlling process died? */ 1533162922Sariff if (old_scp->proc && (old_scp->proc != pfind(old_scp->pid))) 1534162922Sariff old_scp->smode.mode = VT_AUTO; 1535182999Smav if (new_scp->proc && (new_scp->proc != pfind(new_scp->pid))) 1536162922Sariff new_scp->smode.mode = VT_AUTO; 1537162922Sariff 1538162922Sariff /* check the modes and switch approbiatly */ 1539162922Sariff if (old_scp->smode.mode == VT_PROCESS) { 1540162922Sariff old_scp->status |= SWITCH_WAIT_REL; 1541162922Sariff psignal(old_scp->proc, old_scp->smode.relsig); 1542162922Sariff } 1543162922Sariff else { 1544162922Sariff exchange_scr(); 1545162922Sariff if (new_scp->smode.mode == VT_PROCESS) { 1546162922Sariff new_scp->status |= SWITCH_WAIT_ACQ; 1547162922Sariff psignal(new_scp->proc, new_scp->smode.acqsig); 1548162922Sariff } 1549162922Sariff else 1550162922Sariff switch_in_progress = 0; 1551169277Sariff } 1552162922Sariff return 0; 1553162922Sariff} 1554162922Sariff 1555162922Sariffstatic void 1556162922Sariffexchange_scr(void) 1557169277Sariff{ 1558169277Sariff bcopyw(Crtat, old_scp->scr_buf, old_scp->xsize * old_scp->ysize * 2); 1559169277Sariff old_scp->crt_base = old_scp->scr_buf; 1560169277Sariff move_crsr(old_scp, old_scp->xpos, old_scp->ypos); 1561169277Sariff cur_console = new_scp; 1562169277Sariff if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE)){ 1563162922Sariff if (crtc_vga && video_mode_ptr) 1564162922Sariff set_mode(new_scp); 1565162922Sariff } 1566162922Sariff new_scp->crt_base = Crtat; 1567162922Sariff move_crsr(new_scp, new_scp->xpos, new_scp->ypos); 1568162922Sariff bcopyw(new_scp->scr_buf, Crtat, new_scp->xsize * new_scp->ysize * 2); 1569162922Sariff update_leds(new_scp->status); 1570162922Sariff if ((old_scp->status & UNKNOWN_MODE) && crtc_vga) { 1571162922Sariff if (fonts_loaded & FONT_16_LOADED) 1572162922Sariff copy_font(LOAD, 0, 16, font_16); 1573162922Sariff if (fonts_loaded & FONT_8_LOADED) 1574162922Sariff copy_font(LOAD, 1, 8, font_8); 1575162922Sariff if (fonts_loaded & FONT_14_LOADED) 1576162922Sariff copy_font(LOAD, 2, 14, font_14); 1577162922Sariff load_palette(); 1578162922Sariff } 1579182999Smav if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE) 1580182999Smav shfts = ctls = alts = agrs = metas = 0; 1581182999Smav delayed_next_scr = 0; 1582182999Smav} 1583182999Smav 1584162922Sariffstatic void 1585162922Sariffmove_crsr(scr_stat *scp, int x, int y) 1586162922Sariff{ 1587162922Sariff if (x < 0 || y < 0 || x >= scp->xsize || y >= scp->ysize) 1588162922Sariff return; 1589162922Sariff scp->xpos = x; 1590163057Sariff scp->ypos = y; 1591162922Sariff scp->crtat = scp->crt_base + scp->ypos * scp->xsize + scp->xpos; 1592162922Sariff} 1593162922Sariff 1594162922Sariffstatic void 1595162922Sariffscan_esc(scr_stat *scp, u_char c) 1596162922Sariff{ 1597162922Sariff static u_char ansi_col[16] = 1598162922Sariff {0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15}; 1599162922Sariff int i, n; 1600162922Sariff u_short *src, *dst, count; 1601162922Sariff 1602162922Sariff if (scp->term.esc == 1) { 1603162922Sariff switch (c) { 1604162922Sariff 1605162922Sariff case '[': /* Start ESC [ sequence */ 1606162922Sariff scp->term.esc = 2; 1607162922Sariff scp->term.last_param = -1; 1608162922Sariff for (i = scp->term.num_param; i < MAX_ESC_PAR; i++) 1609162922Sariff scp->term.param[i] = 1; 1610162922Sariff scp->term.num_param = 0; 1611162922Sariff return; 1612162922Sariff 1613162922Sariff case 'M': /* Move cursor up 1 line, scroll if at top */ 1614162922Sariff if (scp->ypos > 0) 1615162922Sariff move_crsr(scp, scp->xpos, scp->ypos - 1); 1616162922Sariff else { 1617162922Sariff bcopyw(scp->crt_base, 1618162922Sariff scp->crt_base + scp->xsize, 1619162922Sariff (scp->ysize - 1) * scp->xsize * 1620162922Sariff sizeof(u_short)); 1621162922Sariff fillw(scp->term.cur_attr | scr_map[0x20], 1622162922Sariff scp->crt_base, scp->xsize); 1623162922Sariff } 1624162922Sariff break; 1625162922Sariff#if notyet 1626162922Sariff case 'Q': 1627162922Sariff scp->term.esc = 4; 1628162922Sariff break; 1629162922Sariff#endif 1630162922Sariff case 'c': /* Clear screen & home */ 1631196762Smav clear_screen(scp); 1632163057Sariff break; 1633162922Sariff } 1634162922Sariff } 1635162922Sariff else if (scp->term.esc == 2) { 1636162922Sariff if (c >= '0' && c <= '9') { 1637162922Sariff if (scp->term.num_param < MAX_ESC_PAR) { 1638162922Sariff if (scp->term.last_param != scp->term.num_param) { 1639162922Sariff scp->term.last_param = scp->term.num_param; 1640162922Sariff scp->term.param[scp->term.num_param] = 0; 1641162922Sariff } 1642162922Sariff else 1643162922Sariff scp->term.param[scp->term.num_param] *= 10; 1644162922Sariff scp->term.param[scp->term.num_param] += c - '0'; 1645162922Sariff return; 1646162922Sariff } 1647162922Sariff } 1648162922Sariff scp->term.num_param = scp->term.last_param + 1; 1649162922Sariff switch (c) { 1650162922Sariff 1651162922Sariff case ';': 1652162922Sariff if (scp->term.num_param < MAX_ESC_PAR) 1653162922Sariff return; 1654162922Sariff break; 1655162922Sariff 1656162922Sariff case '=': 1657162922Sariff scp->term.esc = 3; 1658162922Sariff scp->term.last_param = -1; 1659162922Sariff for (i = scp->term.num_param; i < MAX_ESC_PAR; i++) 1660162922Sariff scp->term.param[i] = 1; 1661162922Sariff scp->term.num_param = 0; 1662162922Sariff return; 1663162922Sariff 1664162922Sariff case 'A': /* up n rows */ 1665162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1666196762Smav move_crsr(scp, scp->xpos, scp->ypos - n); 1667196762Smav break; 1668196762Smav 1669196762Smav case 'B': /* down n rows */ 1670196762Smav n = scp->term.param[0]; if (n < 1) n = 1; 1671196762Smav move_crsr(scp, scp->xpos, scp->ypos + n); 1672182999Smav break; 1673182999Smav 1674162922Sariff case 'C': /* right n columns */ 1675162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1676162922Sariff move_crsr(scp, scp->xpos + n, scp->ypos); 1677162922Sariff break; 1678162922Sariff 1679162922Sariff case 'D': /* left n columns */ 1680162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1681162922Sariff move_crsr(scp, scp->xpos - n, scp->ypos); 1682162922Sariff break; 1683162922Sariff 1684162922Sariff case 'E': /* cursor to start of line n lines down */ 1685162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1686162922Sariff move_crsr(scp, 0, scp->ypos + n); 1687162922Sariff break; 1688162922Sariff 1689162922Sariff case 'F': /* cursor to start of line n lines up */ 1690162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1691162922Sariff move_crsr(scp, 0, scp->ypos - n); 1692162922Sariff break; 1693162922Sariff 1694162922Sariff case 'f': /* System V consoles .. */ 1695162922Sariff case 'H': /* Cursor move */ 1696162922Sariff if (scp->term.num_param == 0) 1697162922Sariff move_crsr(scp, 0, 0); 1698162922Sariff else if (scp->term.num_param == 2) 1699162922Sariff move_crsr(scp, scp->term.param[1] - 1, 1700162922Sariff scp->term.param[0] - 1); 1701162922Sariff break; 1702162922Sariff 1703162922Sariff case 'J': /* Clear all or part of display */ 1704162922Sariff if (scp->term.num_param == 0) 1705162922Sariff n = 0; 1706169277Sariff else 1707162922Sariff n = scp->term.param[0]; 1708162922Sariff switch (n) { 1709169277Sariff case 0: /* clear form cursor to end of display */ 1710162922Sariff fillw(scp->term.cur_attr | scr_map[0x20], 1711162922Sariff scp->crtat, scp->crt_base + 1712162922Sariff scp->xsize * scp->ysize - 1713162922Sariff scp->crtat); 1714162922Sariff break; 1715194861Smav case 1: /* clear from beginning of display to cursor */ 1716194861Smav fillw(scp->term.cur_attr | scr_map[0x20], 1717162922Sariff scp->crt_base, 1718162922Sariff scp->crtat - scp->crt_base); 1719194861Smav break; 1720194861Smav case 2: /* clear entire display */ 1721162922Sariff clear_screen(scp); 1722162922Sariff break; 1723162922Sariff } 1724169277Sariff break; 1725162922Sariff 1726169277Sariff case 'K': /* Clear all or part of line */ 1727162922Sariff if (scp->term.num_param == 0) 1728162922Sariff n = 0; 1729162922Sariff else 1730162922Sariff n = scp->term.param[0]; 1731162922Sariff switch (n) { 1732162922Sariff case 0: /* clear form cursor to end of line */ 1733162922Sariff fillw(scp->term.cur_attr | scr_map[0x20], 1734167773Sariff scp->crtat, scp->xsize - scp->xpos); 1735162922Sariff break; 1736162922Sariff case 1: /* clear from beginning of line to cursor */ 1737162922Sariff fillw(scp->term.cur_attr|scr_map[0x20], 1738162922Sariff scp->crtat - (scp->xsize - scp->xpos), 1739162922Sariff (scp->xsize - scp->xpos) + 1); 1740162965Sariff break; 1741169277Sariff case 2: /* clear entire line */ 1742171330Sariff fillw(scp->term.cur_attr|scr_map[0x20], 1743171330Sariff scp->crtat - (scp->xsize - scp->xpos), 1744162922Sariff scp->xsize); 1745162922Sariff break; 1746162922Sariff } 1747167773Sariff break; 1748162922Sariff 1749162922Sariff case 'L': /* Insert n lines */ 1750169277Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1751169277Sariff if (n > scp->ysize - scp->ypos) 1752162922Sariff n = scp->ysize - scp->ypos; 1753162922Sariff src = scp->crt_base + scp->ypos * scp->xsize; 1754162922Sariff dst = src + n * scp->xsize; 1755162922Sariff count = scp->ysize - (scp->ypos + n); 1756169277Sariff bcopyw(src, dst, count * scp->xsize * sizeof(u_short)); 1757162922Sariff fillw(scp->term.cur_attr | scr_map[0x20], src, 1758167773Sariff n * scp->xsize); 1759167773Sariff break; 1760162922Sariff 1761162922Sariff case 'M': /* Delete n lines */ 1762167773Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1763162922Sariff if (n > scp->ysize - scp->ypos) 1764162922Sariff n = scp->ysize - scp->ypos; 1765183097Smav dst = scp->crt_base + scp->ypos * scp->xsize; 1766169277Sariff src = dst + n * scp->xsize; 1767169277Sariff count = scp->ysize - (scp->ypos + n); 1768169277Sariff bcopyw(src, dst, count * scp->xsize * sizeof(u_short)); 1769169277Sariff src = dst + count * scp->xsize; 1770162922Sariff fillw(scp->term.cur_attr | scr_map[0x20], src, 1771169277Sariff n * scp->xsize); 1772167773Sariff break; 1773169277Sariff 1774167773Sariff case 'P': /* Delete n chars */ 1775162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1776162922Sariff if (n > scp->xsize - scp->xpos) 1777162922Sariff n = scp->xsize - scp->xpos; 1778162922Sariff dst = scp->crtat; 1779162922Sariff src = dst + n; 1780169277Sariff count = scp->xsize - (scp->xpos + n); 1781162922Sariff bcopyw(src, dst, count * sizeof(u_short)); 1782162922Sariff src = dst + count; 1783162922Sariff fillw(scp->term.cur_attr | scr_map[0x20], src, n); 1784162922Sariff break; 1785162922Sariff 1786169277Sariff case '@': /* Insert n chars */ 1787162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1788167773Sariff if (n > scp->xsize - scp->xpos) 1789169277Sariff n = scp->xsize - scp->xpos; 1790162922Sariff src = scp->crtat; 1791162922Sariff dst = src + n; 1792162922Sariff count = scp->xsize - (scp->xpos + n); 1793169277Sariff bcopyw(src, dst, count * sizeof(u_short)); 1794162922Sariff fillw(scp->term.cur_attr | scr_map[0x20], src, n); 1795167773Sariff break; 1796167773Sariff 1797162922Sariff case 'S': /* scroll up n lines */ 1798167773Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1799167773Sariff if (n > scp->ysize) 1800167773Sariff n = scp->ysize; 1801167773Sariff bcopyw(scp->crt_base + (scp->xsize * n), 1802162922Sariff scp->crt_base, 1803167773Sariff scp->xsize * (scp->ysize - n) * 1804162922Sariff sizeof(u_short)); 1805167773Sariff fillw(scp->term.cur_attr | scr_map[0x20], 1806162922Sariff scp->crt_base + scp->xsize * 1807162922Sariff (scp->ysize - n), 1808162922Sariff scp->xsize * n); 1809162922Sariff break; 1810162922Sariff 1811162922Sariff case 'T': /* scroll down n lines */ 1812162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1813162922Sariff if (n > scp->ysize) 1814162922Sariff n = scp->ysize; 1815162922Sariff bcopyw(scp->crt_base, 1816162922Sariff scp->crt_base + (scp->xsize * n), 1817162922Sariff scp->xsize * (scp->ysize - n) * 1818162922Sariff sizeof(u_short)); 1819162922Sariff fillw(scp->term.cur_attr | scr_map[0x20], 1820162922Sariff scp->crt_base, scp->xsize * n); 1821162922Sariff break; 1822162922Sariff 1823162922Sariff case 'X': /* delete n characters in line */ 1824162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1825162922Sariff if (n > scp->xsize - scp->xpos) 1826162922Sariff n = scp->xsize - scp->xpos; 1827162922Sariff fillw(scp->term.cur_attr | scr_map[0x20], 1828162922Sariff scp->crt_base + scp->xpos + 1829162922Sariff ((scp->xsize*scp->ypos) * sizeof(u_short)), n); 1830162922Sariff break; 1831162922Sariff 1832162922Sariff case 'Z': /* move n tabs backwards */ 1833162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1834162922Sariff if ((i = scp->xpos & 0xf8) == scp->xpos) 1835162922Sariff i -= 8*n; 1836162922Sariff else 1837162922Sariff i -= 8*(n-1); 1838162922Sariff if (i < 0) 1839162922Sariff i = 0; 1840162922Sariff move_crsr(scp, i, scp->ypos); 1841162922Sariff break; 1842162922Sariff 1843162922Sariff case '`': /* move cursor to column n */ 1844162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1845162922Sariff move_crsr(scp, n - 1, scp->ypos); 1846162922Sariff break; 1847162922Sariff 1848164614Sariff case 'a': /* move cursor n columns to the right */ 1849162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1850162922Sariff move_crsr(scp, scp->xpos + n, scp->ypos); 1851162922Sariff break; 1852162922Sariff 1853162922Sariff case 'd': /* move cursor to row n */ 1854162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1855162922Sariff move_crsr(scp, scp->xpos, n - 1); 1856162922Sariff break; 1857162922Sariff 1858162922Sariff case 'e': /* move cursor n rows down */ 1859162922Sariff n = scp->term.param[0]; if (n < 1) n = 1; 1860162922Sariff move_crsr(scp, scp->xpos, scp->ypos + n); 1861162922Sariff break; 1862162922Sariff 1863162922Sariff case 'm': /* change attribute */ 1864171330Sariff if (scp->term.num_param == 0) { 1865171330Sariff scp->term.cur_attr = scp->term.std_attr; 1866171330Sariff break; 1867171330Sariff } 1868171330Sariff for (i = 0; i < scp->term.num_param; i++) { 1869171330Sariff switch (n = scp->term.param[i]) { 1870171330Sariff case 0: /* back to normal */ 1871171330Sariff scp->term.cur_attr = scp->term.std_attr; 1872162922Sariff break; 1873162922Sariff case 1: /* highlight (bold) */ 1874162922Sariff scp->term.cur_attr &= 0xFF00; 1875162922Sariff scp->term.cur_attr |= 0x0800; 1876162922Sariff break; 1877167773Sariff case 4: /* highlight (underline) */ 1878162922Sariff scp->term.cur_attr &= 0xFF00; 1879182999Smav scp->term.cur_attr |= 0x0800; 1880182999Smav break; 1881162922Sariff case 5: /* blink */ 1882162922Sariff scp->term.cur_attr &= 0xFF00; 1883162922Sariff scp->term.cur_attr |= 0x8000; 1884162922Sariff break; 1885167773Sariff case 7: /* reverse video */ 1886162922Sariff scp->term.cur_attr = scp->term.rev_attr; 1887162922Sariff break; 1888162922Sariff case 30: case 31: /* set fg color */ 1889162922Sariff case 32: case 33: case 34: 1890167773Sariff case 35: case 36: case 37: 1891164614Sariff scp->term.cur_attr = 1892164614Sariff (scp->term.cur_attr & 0xF8FF) 1893162922Sariff | (ansi_col[(n-30) & 7] << 8); 1894162922Sariff break; 1895162922Sariff case 40: case 41: /* set bg color */ 1896162922Sariff case 42: case 43: case 44: 1897162922Sariff case 45: case 46: case 47: 1898162922Sariff scp->term.cur_attr = 1899162922Sariff (scp->term.cur_attr & 0x8FFF) 1900162922Sariff | (ansi_col[(n-40) & 7] << 12); 1901162922Sariff break; 1902162922Sariff } 1903162922Sariff } 1904162922Sariff break; 1905162922Sariff 1906162922Sariff case 'x': 1907164614Sariff if (scp->term.num_param == 0) 1908162922Sariff n = 0; 1909162922Sariff else 1910162922Sariff n = scp->term.param[0]; 1911162922Sariff switch (n) { 1912188656Smav case 0: /* reset attributes */ 1913171330Sariff scp->term.cur_attr = scp->term.std_attr = 1914164614Sariff current_default->std_attr; 1915164614Sariff scp->term.rev_attr = current_default->rev_attr; 1916171330Sariff break; 1917162922Sariff case 1: /* set ansi background */ 1918162922Sariff scp->term.cur_attr = scp->term.std_attr = 1919162922Sariff (scp->term.std_attr & 0x0F00) | 1920162922Sariff (ansi_col[(scp->term.param[1])&0x0F]<<12); 1921162922Sariff break; 1922162922Sariff case 2: /* set ansi foreground */ 1923162922Sariff scp->term.cur_attr = scp->term.std_attr = 1924162922Sariff (scp->term.std_attr & 0xF000) | 1925162922Sariff (ansi_col[(scp->term.param[1])&0x0F]<<8); 1926162922Sariff break; 1927162922Sariff case 3: /* set ansi attribute directly */ 1928162922Sariff scp->term.cur_attr = scp->term.std_attr = 1929162922Sariff (scp->term.param[1]&0xFF)<<8; 1930162922Sariff break; 1931162922Sariff case 5: /* set ansi reverse video background */ 1932162922Sariff scp->term.rev_attr = 1933162922Sariff (scp->term.rev_attr & 0x0F00) | 1934162922Sariff (ansi_col[(scp->term.param[1])&0x0F]<<12); 1935162922Sariff break; 1936162922Sariff case 6: /* set ansi reverse video foreground */ 1937162922Sariff scp->term.rev_attr = 1938162922Sariff (scp->term.rev_attr & 0xF000) | 1939162922Sariff (ansi_col[(scp->term.param[1])&0x0F]<<8); 1940162922Sariff break; 1941162922Sariff case 7: /* set ansi reverse video directly */ 1942162922Sariff scp->term.rev_attr = 1943162922Sariff (scp->term.param[1]&0xFF)<<8; 1944162922Sariff break; 1945162922Sariff } 1946162922Sariff break; 1947162922Sariff 1948162922Sariff case 'z': /* switch to (virtual) console n */ 1949162922Sariff if (scp->term.num_param == 1) 1950162922Sariff switch_scr(scp, scp->term.param[0]); 1951162922Sariff break; 1952162922Sariff } 1953162922Sariff } 1954162922Sariff else if (scp->term.esc == 3) { 1955162922Sariff if (c >= '0' && c <= '9') { 1956162922Sariff if (scp->term.num_param < MAX_ESC_PAR) { 1957162922Sariff if (scp->term.last_param != scp->term.num_param) { 1958162922Sariff scp->term.last_param = scp->term.num_param; 1959162922Sariff scp->term.param[scp->term.num_param] = 0; 1960162922Sariff } 1961162922Sariff else 1962162922Sariff scp->term.param[scp->term.num_param] *= 10; 1963162922Sariff scp->term.param[scp->term.num_param] += c - '0'; 1964162922Sariff return; 1965162922Sariff } 1966162922Sariff } 1967162922Sariff scp->term.num_param = scp->term.last_param + 1; 1968162922Sariff switch (c) { 1969162922Sariff 1970162922Sariff case ';': 1971162922Sariff if (scp->term.num_param < MAX_ESC_PAR) 1972162922Sariff return; 1973162922Sariff break; 1974162922Sariff 1975162922Sariff case 'A': /* set display border color */ 1976162922Sariff if (scp->term.num_param == 1) 1977162922Sariff scp->border=scp->term.param[0] & 0xff; 1978162922Sariff if (scp == cur_console) 1979162922Sariff set_border(scp->border); 1980162922Sariff break; 1981162922Sariff 1982162922Sariff case 'B': /* set bell pitch and duration */ 1983162922Sariff if (scp->term.num_param == 2) { 1984162922Sariff scp->bell_pitch = scp->term.param[0]; 1985162922Sariff scp->bell_duration = scp->term.param[1]*10; 1986162922Sariff } 1987162922Sariff break; 1988162922Sariff 1989162922Sariff case 'C': /* set cursor type & shape */ 1990162922Sariff if (scp->term.num_param == 1) { 1991162922Sariff if (scp->term.param[0] & 0x01) 1992162922Sariff configuration |= BLINK_CURSOR; 1993162922Sariff else 1994162922Sariff configuration &= ~BLINK_CURSOR; 1995162922Sariff } 1996162922Sariff#if 0 1997162922Sariff else if (scp->term.num_param == 2) { 1998162922Sariff scp->cursor_start = scp->term.param[0] & 0x1F; 1999162922Sariff scp->cursor_end = scp->term.param[1] & 0x1F; 2000162922Sariff if (scp == cur_console) 2001162922Sariff cursor_shape(scp->cursor_start, 2002162922Sariff scp->cursor_end); 2003162922Sariff } 2004162922Sariff#endif 2005162922Sariff break; 2006162922Sariff 2007182999Smav case 'F': /* set ansi foreground */ 2008182999Smav if (scp->term.num_param == 1) 2009162922Sariff scp->term.cur_attr = scp->term.std_attr = 2010182999Smav (scp->term.std_attr & 0xF000) 2011162922Sariff | ((scp->term.param[0] & 0x0F) << 8); 2012182999Smav break; 2013182999Smav 2014162922Sariff case 'G': /* set ansi background */ 2015182999Smav if (scp->term.num_param == 1) 2016162922Sariff scp->term.cur_attr = scp->term.std_attr = 2017162922Sariff (scp->term.std_attr & 0x0F00) 2018169277Sariff | ((scp->term.param[0] & 0x0F) << 12); 2019162922Sariff break; 2020162922Sariff 2021162922Sariff case 'H': /* set ansi reverse video foreground */ 2022162922Sariff if (scp->term.num_param == 1) 2023162922Sariff scp->term.rev_attr = 2024162922Sariff (scp->term.rev_attr & 0xF000) 2025162922Sariff | ((scp->term.param[0] & 0x0F) << 8); 2026162922Sariff break; 2027169277Sariff 2028162922Sariff case 'I': /* set ansi reverse video background */ 2029162922Sariff if (scp->term.num_param == 1) 2030162922Sariff scp->term.rev_attr = 2031162922Sariff (scp->term.rev_attr & 0x0F00) 2032162922Sariff | ((scp->term.param[0] & 0x0F) << 12); 2033162922Sariff break; 2034162922Sariff } 2035162922Sariff } 2036162922Sariff scp->term.esc = 0; 2037162922Sariff} 2038162922Sariff 2039162922Sariffstatic void 2040162922Sariffundraw_cursor(scr_stat *scp) 2041162922Sariff{ 2042162922Sariff if (scp->cursor_saveunder) { 2043162922Sariff *scp->crtat = scp->cursor_saveunder; 2044162922Sariff scp->cursor_saveunder = NULL; 2045162922Sariff } 2046162922Sariff} 2047162922Sariff 2048162922Sariffstatic void 2049162922Sariffdraw_cursor(scr_stat *scp) 2050162922Sariff{ 2051162922Sariff scp->cursor_saveunder = *scp->crtat; 2052162922Sariff if ((scp->cursor_saveunder & 0x7000) == 0x7000) { 2053162922Sariff *scp->crtat &= 0x8fff; 2054162922Sariff if(!(scp->cursor_saveunder & 0x0700)) 2055162922Sariff *scp->crtat |= 0x0700; 2056162922Sariff } else { 2057162922Sariff *scp->crtat |= 0x7000; 2058162922Sariff if ((scp->cursor_saveunder & 0x0f00) == 0x0700) 2059162922Sariff *scp->crtat &= 0xf8ff; 2060162922Sariff } 2061162922Sariff} 2062172811Sariff 2063162922Sariffstatic void 2064172811Sariffansi_put(scr_stat *scp, u_char c) 2065162922Sariff{ 2066162922Sariff if (scp->status & UNKNOWN_MODE) 2067182999Smav return; 2068162922Sariff 2069162922Sariff /* make screensaver happy */ 2070162922Sariff if (scp == cur_console) { 2071162922Sariff scrn_time_stamp = time.tv_sec; 2072162922Sariff if (scrn_blanked) 2073162922Sariff SCRN_SAVER(0); 2074182999Smav } 2075162922Sariff write_in_progress++; 2076162922Sariff if (scp->term.esc) 2077162922Sariff scan_esc(scp, c); 2078162922Sariff else switch(c) { 2079162922Sariff case 0x1B: /* start escape sequence */ 2080162922Sariff scp->term.esc = 1; 2081162922Sariff scp->term.num_param = 0; 2082162922Sariff break; 2083162922Sariff case 0x07: 2084164614Sariff do_bell(scp, scp->bell_pitch, scp->bell_duration); 2085164614Sariff break; 2086162922Sariff case '\t': /* non-destructive tab */ 2087162922Sariff scp->crtat += (8 - scp->xpos % 8); 2088162922Sariff scp->xpos += (8 - scp->xpos % 8); 2089162922Sariff break; 2090182999Smav case '\b': /* non-destructive backspace */ 2091162922Sariff if (scp->crtat > scp->crt_base) { 2092162922Sariff scp->crtat--; 2093162922Sariff if (scp->xpos > 0) 2094163057Sariff scp->xpos--; 2095162922Sariff else { 2096162922Sariff scp->xpos += scp->xsize - 1; 2097162922Sariff scp->ypos--; 2098162922Sariff } 2099162922Sariff } 2100162922Sariff break; 2101162922Sariff case '\r': /* return to pos 0 */ 2102182999Smav move_crsr(scp, 0, scp->ypos); 2103162922Sariff break; 2104162922Sariff case '\n': /* newline, same pos */ 2105162922Sariff scp->crtat += scp->xsize; 2106162922Sariff scp->ypos++; 2107162922Sariff break; 2108162922Sariff case '\f': /* form feed, clears screen */ 2109162922Sariff clear_screen(scp); 2110162922Sariff break; 2111162922Sariff default: 2112163057Sariff /* Print only printables */ 2113184089Smav *scp->crtat = (scp->term.cur_attr | scr_map[c]); 2114162922Sariff scp->crtat++; 2115162922Sariff if (++scp->xpos >= scp->xsize) { 2116162922Sariff scp->xpos = 0; 2117162922Sariff scp->ypos++; 2118162922Sariff } 2119162922Sariff break; 2120162922Sariff } 2121182999Smav /* do we have to scroll ?? */ 2122182999Smav if (scp->crtat >= scp->crt_base + scp->ysize * scp->xsize) { 2123182999Smav /* process history lines begin */ 2124182999Smav if (scp->history_head+scp->xsize > scp->history+HISTORY_SIZE) { 2125182999Smav bcopy(scp->history + scp->xsize, scp->history, 2126182999Smav (HISTORY_SIZE - scp->xsize) * sizeof(u_short)); 2127182999Smav bcopyw(scp->crt_base, scp->history_head - scp->xsize, 2128182999Smav scp->xsize * sizeof(u_short)); 2129182999Smav } 2130182999Smav else { 2131182999Smav bcopyw(scp->crt_base, scp->history_head, 2132184089Smav scp->xsize * sizeof(u_short)); 2133182999Smav scp->history_head += scp->xsize; 2134182999Smav } 2135184089Smav /* process history lines end */ 2136182999Smav 2137182999Smav bcopyw(scp->crt_base + scp->xsize, scp->crt_base, 2138182999Smav scp->xsize * (scp->ysize - 1) * sizeof(u_short)); 2139182999Smav fillw(scp->term.cur_attr | scr_map[0x20], 2140182999Smav scp->crt_base + scp->xsize * (scp->ysize - 1), 2141182999Smav scp->xsize); 2142182999Smav scp->crtat -= scp->xsize; 2143182999Smav scp->ypos--; 2144182999Smav } 2145182999Smav write_in_progress--; 2146182999Smav if (delayed_next_scr) 2147182999Smav switch_scr(scp, delayed_next_scr - 1); 2148162922Sariff} 2149162922Sariff 2150162922Sariffstatic void 2151162922Sariffscinit(void) 2152162922Sariff{ 2153162922Sariff u_short volatile *cp = Crtat + (CGA_BUF-MONO_BUF)/sizeof(u_short), was; 2154183097Smav unsigned cursorat; 2155182999Smav int i; 2156163057Sariff 2157162922Sariff /* 2158182999Smav * catch that once in a blue moon occurence when scinit is called 2159182999Smav * TWICE, adding the CGA_BUF offset again -> poooff 2160182999Smav */ 2161182999Smav if (crtat != 0) 2162183024Smav return; 2163182999Smav /* 2164182999Smav * Crtat initialized to point to MONO buffer, if not present change 2165162922Sariff * to CGA_BUF offset. ONLY ADD the difference since locore.s adds 2166162922Sariff * in the remapped offset at the "right" time 2167182999Smav */ 2168182999Smav was = *cp; 2169182999Smav *cp = (u_short) 0xA55A; 2170162922Sariff if (*cp != 0xA55A) 2171162922Sariff crtc_addr = MONO_BASE; 2172182999Smav else { 2173182999Smav *cp = was; 2174182999Smav crtc_addr = COLOR_BASE; 2175182999Smav Crtat = Crtat + (CGA_BUF-MONO_BUF)/sizeof(u_short); 2176162922Sariff } 2177162922Sariff 2178162922Sariff /* extract cursor location */ 2179182999Smav outb(crtc_addr,14); 2180162922Sariff cursorat = inb(crtc_addr+1)<<8 ; 2181182999Smav outb(crtc_addr,15); 2182162922Sariff cursorat |= inb(crtc_addr+1); 2183162922Sariff crtat = Crtat + cursorat; 2184162965Sariff 2185162965Sariff /* move hardware cursor out of the way */ 2186162922Sariff outb(crtc_addr,14); 2187162922Sariff outb(crtc_addr+1, 0xff); 2188162965Sariff outb(crtc_addr,15); 2189162922Sariff outb(crtc_addr+1, 0xff); 2190162922Sariff 2191182999Smav /* is this a VGA or higher ? */ 2192182999Smav outb(crtc_addr, 7); 2193162922Sariff if (inb(crtc_addr) == 7) { 2194182999Smav u_long pa; 2195182999Smav u_long segoff; 2196182999Smav 2197162922Sariff crtc_vga = 1; 2198182999Smav 2199182999Smav /* 2200182999Smav * Get the BIOS video mode pointer. 2201182999Smav */ 2202182999Smav segoff = *(u_long *)pa_to_va(0x4a8); 2203182999Smav pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff)); 2204182999Smav if (ISMAPPED(pa, sizeof(u_long))) { 2205182999Smav segoff = *(u_long *)pa_to_va(pa); 2206182999Smav pa = (((segoff & 0xffff0000) >> 12) 2207182999Smav + (segoff & 0xffff)); 2208182999Smav if (ISMAPPED(pa, 64)) 2209182999Smav video_mode_ptr = (char *)pa_to_va(pa); 2210182999Smav } 2211182999Smav } 2212182999Smav current_default = &user_default; 2213182999Smav console[0] = &main_console; 2214182999Smav init_scp(console[0]); 2215182999Smav console[0]->crt_base = Crtat; 2216182999Smav console[0]->crtat = crtat; 2217182999Smav console[0]->xpos = cursorat % COL; 2218182999Smav console[0]->ypos = cursorat / COL; 2219182999Smav cur_console = console[0]; 2220182999Smav for (i=1; i<MAXCONS; i++) 2221182999Smav console[i] = NULL; 2222162922Sariff kernel_console.esc = 0; 2223162922Sariff kernel_console.std_attr = kernel_default.std_attr; 2224162922Sariff kernel_console.rev_attr = kernel_default.rev_attr; 2225162922Sariff kernel_console.cur_attr = kernel_default.std_attr; 2226162922Sariff /* initialize mapscrn array to a one to one map */ 2227162922Sariff for (i=0; i<sizeof(scr_map); i++) 2228162922Sariff scr_map[i] = i; 2229169277Sariff} 2230162922Sariff 2231162922Sariffstatic scr_stat 2232169277Sariff*alloc_scp() 2233162922Sariff{ 2234169277Sariff scr_stat *scp; 2235169277Sariff 2236162922Sariff scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_NOWAIT); 2237162922Sariff init_scp(scp); 2238162922Sariff scp->crt_base = scp->crtat = scp->scr_buf = 2239169277Sariff (u_short *)malloc(scp->xsize*scp->ysize*2, M_DEVBUF, M_NOWAIT); 2240162922Sariff if (crtc_vga && video_mode_ptr) 2241169277Sariff set_mode(scp); 2242162922Sariff clear_screen(scp); 2243162922Sariff return scp; 2244162922Sariff} 2245162922Sariff 2246169277Sariffstatic void 2247162922Sariffinit_scp(scr_stat *scp) 2248169277Sariff{ 2249169277Sariff scp->mode = M_VGA_C80x25; 2250169277Sariff scp->xsize = COL; 2251169277Sariff scp->ysize = ROW; 2252169277Sariff scp->term.esc = 0; 2253169277Sariff scp->term.std_attr = current_default->std_attr; 2254169277Sariff scp->term.rev_attr = current_default->rev_attr; 2255162922Sariff scp->term.cur_attr = scp->term.std_attr; 2256162922Sariff scp->border = BG_BLACK; 2257162922Sariff scp->cursor_start = -1; 2258169277Sariff scp->cursor_end = -1; 2259169277Sariff scp->cursor_protect = 0; 2260169277Sariff scp->cursor_saveunder = scr_map[0x20]; 2261169277Sariff scp->bell_pitch = BELL_PITCH; 2262169277Sariff scp->bell_duration = BELL_DURATION; 2263169277Sariff scp->status = (*(char *)pa_to_va(0x417) & 0x20) ? NLKED : 0; 2264169277Sariff scp->pid = 0; 2265169277Sariff scp->proc = NULL; 2266169277Sariff scp->smode.mode = VT_AUTO; 2267169277Sariff scp->history_head = scp->history_pos = scp->history; 2268169277Sariff} 2269169277Sariff 2270169277Sariffstatic void 2271169277Sariffscput(u_char c) 2272169277Sariff{ 2273169277Sariff scr_stat *scp = console[0]; 2274182999Smav term_stat save; 2275169277Sariff 2276182999Smav if (crtat == 0) 2277169277Sariff scinit(); 2278169277Sariff/* SOS 2279169277Sariff if (!write_in_progress) { 2280169277Sariff ++write_in_progress; 2281169277Sariff*/ 2282162922Sariff save = scp->term; 2283169277Sariff scp->term = kernel_console; 2284169277Sariff current_default = &kernel_default; 2285169277Sariff scp->cursor_protect = 1; 2286169277Sariff undraw_cursor(scp); 2287169277Sariff ansi_put(scp, c); 2288169277Sariff draw_cursor(scp); 2289169277Sariff scp->cursor_protect = 0; 2290169277Sariff kernel_console = scp->term; 2291169277Sariff current_default = &user_default; 2292169277Sariff scp->term = save; 2293169277Sariff/* SOS 2294182999Smav --write_in_progress; 2295169277Sariff } else { 2296182999Smav if (console_buffer_count < CONSOLE_BUFSIZE) 2297169277Sariff console_buffer[console_buffer_count++] = c; 2298169277Sariff } 2299182999Smav*/ 2300169277Sariff} 2301162922Sariff 2302169277Sariffstatic u_char 2303162922Sariff*get_fstr(u_int c, u_int *len) 2304162922Sariff{ 2305162922Sariff u_int i; 2306169277Sariff 2307169277Sariff if (!(c & FKEY)) 2308162922Sariff return(NULL); 2309162922Sariff i = (c & 0xFF) - F_FN; 2310162922Sariff if (i > n_fkey_tab) 2311182999Smav return(NULL); 2312182999Smav *len = fkey_tab[i].len; 2313182999Smav return(fkey_tab[i].str); 2314182999Smav} 2315182999Smav 2316182999Smavstatic void 2317182999Smavupdate_leds(int which) 2318182999Smav{ 2319182999Smav int s; 2320182999Smav static u_char xlate_leds[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; 2321182999Smav 2322182999Smav /* replace CAPS led with ALTGR led for ALTGR keyboards */ 2323182999Smav if (key_map.n_keys > ALTGR_OFFSET) { 2324182999Smav if (which & ALKED) 2325182999Smav which |= CLKED; 2326182999Smav else 2327182999Smav which &= ~CLKED; 2328182999Smav } 2329182999Smav s = spltty(); 2330182999Smav kbd_cmd(KB_SETLEDS); 2331182999Smav kbd_cmd(xlate_leds[which & LED_MASK]); 2332182999Smav splx(s); 2333182999Smav} 2334182999Smav 2335182999Smav/* 2336182999Smav * scgetc(noblock) - get character from keyboard. 2337182999Smav * If noblock = 0 wait until a key is pressed. 2338182999Smav * Else return NOKEY. 2339182999Smav */ 2340182999Smavu_int 2341182999Smavscgetc(int noblock) 2342182999Smav{ 2343182999Smav u_char scancode, keycode; 2344182999Smav u_int state, action; 2345182999Smav struct key_t *key; 2346182999Smav static u_char esc_flag = 0, compose = 0; 2347182999Smav static u_int chr = 0; 2348182999Smav 2349182999Smavnext_code: 2350182999Smav kbd_wait(); 2351182999Smav /* First see if there is something in the keyboard port */ 2352182999Smav if (inb(KB_STAT) & KB_BUF_FULL) 2353182999Smav scancode = inb(KB_DATA); 2354182999Smav else if (noblock) 2355182999Smav return(NOKEY); 2356182999Smav else 2357182999Smav goto next_code; 2358182999Smav 2359182999Smav if (cur_console->status & KBD_RAW_MODE) 2360182999Smav return scancode; 2361182999Smav#if ASYNCH 2362182999Smav if (scancode == KB_ACK || scancode == KB_RESEND) { 2363182999Smav kbd_reply = scancode; 2364182999Smav if (noblock) 2365182999Smav return(NOKEY); 2366182999Smav goto next_code; 2367182999Smav } 2368182999Smav#endif 2369182999Smav keycode = scancode & 0x7F; 2370182999Smav switch (esc_flag) { 2371182999Smav case 0x00: /* normal scancode */ 2372182999Smav switch(scancode) { 2373182999Smav case 0xB8: /* left alt (compose key) */ 2374182999Smav if (compose) { 2375182999Smav compose = 0; 2376182999Smav if (chr > 255) { 2377182999Smav do_bell(cur_console, 2378182999Smav BELL_PITCH, BELL_DURATION); 2379182999Smav chr = 0; 2380182999Smav } 2381182999Smav } 2382182999Smav break; 2383182999Smav case 0x38: 2384182999Smav if (!compose) { 2385182999Smav compose = 1; 2386182999Smav chr = 0; 2387182999Smav } 2388162922Sariff break; 2389162922Sariff case 0xE0: 2390162922Sariff case 0xE1: 2391166965Sariff esc_flag = scancode; 2392162922Sariff goto next_code; 2393182999Smav } 2394182999Smav break; 2395162922Sariff case 0xE0: /* 0xE0 prefix */ 2396162922Sariff esc_flag = 0; 2397162922Sariff switch (keycode) { 2398162922Sariff case 0x1C: /* right enter key */ 2399182999Smav keycode = 0x59; 2400162922Sariff break; 2401162922Sariff case 0x1D: /* right ctrl key */ 2402162922Sariff keycode = 0x5A; 2403162922Sariff break; 2404166965Sariff case 0x35: /* keypad divide key */ 2405166965Sariff keycode = 0x5B; 2406182999Smav break; 2407182999Smav case 0x37: /* print scrn key */ 2408182999Smav keycode = 0x5C; 2409182999Smav break; 2410182999Smav case 0x38: /* right alt key (alt gr) */ 2411182999Smav keycode = 0x5D; 2412182999Smav break; 2413162965Sariff case 0x47: /* grey home key */ 2414165281Sariff keycode = 0x5E; 2415165281Sariff break; 2416165281Sariff case 0x48: /* grey up arrow key */ 2417165281Sariff keycode = 0x5F; 2418165281Sariff break; 2419165281Sariff case 0x49: /* grey page up key */ 2420165281Sariff keycode = 0x60; 2421165281Sariff break; 2422165281Sariff case 0x4B: /* grey left arrow key */ 2423165281Sariff keycode = 0x61; 2424167610Sariff break; 2425167610Sariff case 0x4D: /* grey right arrow key */ 2426165281Sariff keycode = 0x62; 2427165281Sariff break; 2428162965Sariff case 0x4F: /* grey end key */ 2429162965Sariff keycode = 0x63; 2430162922Sariff break; 2431162965Sariff case 0x50: /* grey down arrow key */ 2432162922Sariff keycode = 0x64; 2433162922Sariff break; 2434162922Sariff case 0x51: /* grey page down key */ 2435162922Sariff keycode = 0x65; 2436162922Sariff break; 2437162922Sariff case 0x52: /* grey insert key */ 2438162922Sariff keycode = 0x66; 2439162922Sariff break; 2440162922Sariff case 0x53: /* grey delete key */ 2441162922Sariff keycode = 0x67; 2442162922Sariff break; 2443162922Sariff 2444162922Sariff /* the following 3 are only used on the MS "Natural" keyboard */ 2445162922Sariff case 0x5b: /* left Window key */ 2446162922Sariff keycode = 0x69; 2447162922Sariff break; 2448162922Sariff case 0x5c: /* right Window key */ 2449162922Sariff keycode = 0x6a; 2450162922Sariff break; 2451162922Sariff case 0x5d: /* menu key */ 2452162922Sariff keycode = 0x6b; 2453162922Sariff break; 2454162922Sariff default: /* ignore everything else */ 2455166965Sariff goto next_code; 2456172811Sariff } 2457172811Sariff break; 2458166965Sariff case 0xE1: /* 0xE1 prefix */ 2459166965Sariff esc_flag = 0; 2460166965Sariff if (keycode == 0x1D) 2461166965Sariff esc_flag = 0x1D; 2462166965Sariff goto next_code; 2463166965Sariff /* NOT REACHED */ 2464166965Sariff case 0x1D: /* pause / break */ 2465169277Sariff esc_flag = 0; 2466169277Sariff if (keycode != 0x45) 2467169277Sariff goto next_code; 2468169277Sariff keycode = 0x68; 2469169277Sariff break; 2470169277Sariff } 2471166965Sariff 2472186430Smav /* if scroll-lock pressed allow history browsing */ 2473166965Sariff if (cur_console->status & SLKED) { 2474166965Sariff cur_console->cursor_protect = 1; 2475166965Sariff undraw_cursor(cur_console); 2476166965Sariff if (!(cur_console->status & BUFFER_SAVED)) { 2477166965Sariff bcopyw(Crtat, cur_console->scr_buf, 2478166965Sariff cur_console->xsize * cur_console->ysize * 2479166965Sariff sizeof(u_short)); 2480166965Sariff cur_console->status |= BUFFER_SAVED; 2481166965Sariff cur_console->history_pos = cur_console->history_head; 2482166965Sariff } 2483166965Sariff switch (scancode) { 2484166965Sariff case 0x50: /* down arrow key */ 2485167454Sariff if (cur_console->history_pos < cur_console->history_head) { 2486167454Sariff bcopyw(cur_console->crt_base+cur_console->xsize, 2487167454Sariff cur_console->crt_base, 2488167454Sariff cur_console->xsize * (cur_console->ysize - 1) * 2489167454Sariff sizeof(u_short)); 2490167454Sariff if (cur_console->history_pos + 2491166965Sariff (cur_console->xsize*cur_console->ysize) < 2492186430Smav cur_console->history_head) { 2493169277Sariff /* from history buffer */ 2494169277Sariff bcopyw(cur_console->history_pos + 2495169277Sariff cur_console->xsize*(cur_console->ysize), 2496169277Sariff cur_console->crt_base + 2497169277Sariff cur_console->xsize*(cur_console->ysize-1), 2498169277Sariff cur_console->xsize * sizeof(u_short)); 2499169277Sariff } 2500169277Sariff else { 2501169277Sariff /* from screen buffer */ 2502169277Sariff bcopyw(cur_console->scr_buf + 2503169277Sariff cur_console->xsize * cur_console->ysize - 2504169277Sariff (cur_console->history_head - 2505169277Sariff cur_console->history_pos), 2506169277Sariff cur_console->crt_base + 2507169277Sariff cur_console->xsize*(cur_console->ysize-1), 2508169277Sariff cur_console->xsize * sizeof(u_short)); 2509169277Sariff } 2510178324Sariff cur_console->history_pos += cur_console->xsize; 2511178324Sariff } 2512178324Sariff else 2513178324Sariff do_bell(cur_console, BELL_PITCH, BELL_DURATION); 2514178324Sariff goto next_code; 2515178324Sariff 2516178324Sariff case 0x48: /* up arrow key */ 2517178324Sariff if (cur_console->history_pos > cur_console->history) { 2518178324Sariff bcopyw(cur_console->crt_base, 2519178324Sariff cur_console->crt_base + cur_console->xsize, 2520169277Sariff cur_console->xsize * cur_console->ysize * 2521169277Sariff sizeof(u_short)); 2522169277Sariff bcopyw(cur_console->history_pos - cur_console->xsize, 2523169277Sariff cur_console->crt_base, 2524169277Sariff cur_console->xsize * sizeof(u_short)); 2525169277Sariff cur_console->history_pos -= cur_console->xsize; 2526169277Sariff } 2527169277Sariff else 2528169277Sariff do_bell(cur_console, BELL_PITCH, BELL_DURATION); 2529169277Sariff goto next_code; 2530169277Sariff } 2531169277Sariff } 2532169277Sariff 2533169277Sariff if (compose) { 2534169277Sariff switch (scancode) { 2535169277Sariff /* key pressed process it */ 2536169277Sariff case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */ 2537182999Smav chr = (scancode - 0x40) + chr*10; 2538182999Smav goto next_code; 2539182999Smav case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */ 2540182999Smav chr = (scancode - 0x47) + chr*10; 2541171141Sariff goto next_code; 2542190630Smav case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */ 2543190630Smav chr = (scancode - 0x4E) + chr*10; 2544169277Sariff goto next_code; 2545190630Smav case 0x52: /* keypad 0 */ 2546190630Smav chr *= 10; 2547190630Smav goto next_code; 2548190630Smav 2549182999Smav /* key release, no interest here */ 2550169277Sariff case 0xC7: case 0xC8: case 0xC9: /* keypad 7,8,9 */ 2551190630Smav case 0xCB: case 0xCC: case 0xCD: /* keypad 4,5,6 */ 2552190630Smav case 0xCF: case 0xD0: case 0xD1: /* keypad 1,2,3 */ 2553190630Smav case 0xD2: /* keypad 0 */ 2554190630Smav goto next_code; 2555190630Smav 2556169277Sariff case 0x38: /* left alt key */ 2557182999Smav break; 2558182999Smav default: 2559169277Sariff if (chr) { 2560182999Smav compose = chr = 0; 2561182999Smav do_bell(cur_console, BELL_PITCH, BELL_DURATION); 2562182999Smav goto next_code; 2563182999Smav } 2564182999Smav break; 2565182999Smav } 2566182999Smav } 2567182999Smav 2568182999Smav state = (shfts ? 1 : 0 ) | (2 * (ctls ? 1 : 0)) | (4 * (alts ? 1 : 0)); 2569169277Sariff if ((!agrs && (cur_console->status & ALKED)) 2570182999Smav || (agrs && !(cur_console->status & ALKED))) 2571182999Smav keycode += ALTGR_OFFSET; 2572182999Smav key = &key_map.key[keycode]; 2573182999Smav if ( ((key->flgs & FLAG_LOCK_C) && (cur_console->status & CLKED)) 2574182999Smav || ((key->flgs & FLAG_LOCK_N) && (cur_console->status & NLKED)) ) 2575182999Smav state ^= 1; 2576182999Smav 2577189879Smav /* Check for make/break */ 2578189879Smav action = key->map[state]; 2579174578Sariff if (scancode & 0x80) { /* key released */ 2580189879Smav if (key->spcl & 0x80) { 2581189879Smav switch (action) { 2582174578Sariff case LSH: 2583174578Sariff shfts &= ~1; 2584189879Smav break; 2585162922Sariff case RSH: 2586162922Sariff shfts &= ~2; 2587182999Smav break; 2588182999Smav case LCTR: 2589182999Smav ctls &= ~1; 2590182999Smav break; 2591182999Smav case RCTR: 2592182999Smav ctls &= ~2; 2593182999Smav break; 2594182999Smav case LALT: 2595182999Smav alts &= ~1; 2596182999Smav break; 2597182999Smav case RALT: 2598182999Smav alts &= ~2; 2599182999Smav break; 2600166965Sariff case NLK: 2601166965Sariff nlkcnt = 0; 2602166965Sariff break; 2603182999Smav case CLK: 2604166965Sariff clkcnt = 0; 2605166965Sariff break; 2606166965Sariff case SLK: 2607162922Sariff slkcnt = 0; 2608162922Sariff break; 2609162922Sariff case ASH: 2610166965Sariff agrs = 0; 2611166965Sariff break; 2612166965Sariff case ALK: 2613166965Sariff alkcnt = 0; 2614166965Sariff break; 2615166965Sariff case META: 2616166965Sariff metas = 0; 2617166965Sariff break; 2618166965Sariff } 2619166965Sariff } 2620182999Smav if (chr && !compose) { 2621166965Sariff action = chr; 2622166965Sariff chr = 0; 2623166965Sariff return(action); 2624166965Sariff } 2625166965Sariff } else { 2626166965Sariff /* key pressed */ 2627166965Sariff if (key->spcl & (0x80>>state)) { 2628166965Sariff switch (action) { 2629182999Smav /* LOCKING KEYS */ 2630166965Sariff case NLK: 2631166965Sariff if (!nlkcnt) { 2632166965Sariff nlkcnt++; 2633166965Sariff if (cur_console->status & NLKED) 2634166965Sariff cur_console->status &= ~NLKED; 2635166965Sariff else 2636162922Sariff cur_console->status |= NLKED; 2637162922Sariff update_leds(cur_console->status); 2638162922Sariff } 2639162922Sariff break; 2640162922Sariff case CLK: 2641186912Smav if (!clkcnt) { 2642162922Sariff clkcnt++; 2643162922Sariff if (cur_console->status & CLKED) 2644186912Smav cur_console->status &= ~CLKED; 2645162922Sariff else 2646162922Sariff cur_console->status |= CLKED; 2647162922Sariff update_leds(cur_console->status); 2648162922Sariff } 2649166965Sariff break; 2650162922Sariff case SLK: 2651162922Sariff if (!slkcnt) { 2652162922Sariff slkcnt++; 2653182999Smav if (cur_console->status & SLKED) { 2654162922Sariff cur_console->status &= ~SLKED; 2655162922Sariff if (cur_console->status & BUFFER_SAVED){ 2656162922Sariff bcopyw(cur_console->scr_buf, Crtat, 2657162922Sariff cur_console->xsize * 2658162922Sariff cur_console->ysize * 2659162922Sariff sizeof(u_short)); 2660162922Sariff cur_console->status&=~BUFFER_SAVED; 2661162965Sariff cur_console->history_pos = 2662162922Sariff cur_console->history_head; 2663182999Smav draw_cursor(cur_console); 2664182999Smav cur_console->cursor_protect = 0; 2665162922Sariff } 2666186912Smav pcstart(VIRTUAL_TTY(get_scr_num())); 2667186912Smav } 2668186912Smav else 2669186912Smav cur_console->status |= SLKED; 2670162922Sariff update_leds(cur_console->status); 2671162922Sariff } 2672162922Sariff break; 2673162922Sariff case ALK: 2674186912Smav if (!alkcnt) { 2675186912Smav alkcnt++; 2676186912Smav if (cur_console->status & ALKED) 2677186912Smav cur_console->status &= ~ALKED; 2678186912Smav else 2679162922Sariff cur_console->status |= ALKED; 2680162922Sariff update_leds(cur_console->status); 2681162922Sariff } 2682182999Smav break; 2683182999Smav 2684182999Smav /* NON-LOCKING KEYS */ 2685182999Smav case NOP: 2686182999Smav break; 2687182999Smav case RBT: 2688182999Smav shutdown_nice(); 2689182999Smav break; 2690182999Smav case SUSP: 2691182999Smav break; 2692182999Smav 2693182999Smav case DBG: 2694182999Smav#ifdef DDB /* try to switch to console 0 */ 2695182999Smav if (cur_console->smode.mode == VT_AUTO && 2696182999Smav console[0]->smode.mode == VT_AUTO) 2697182999Smav switch_scr(cur_console, 0); 2698182999Smav Debugger("manual escape to debugger"); 2699182999Smav return(NOKEY); 2700182999Smav#else 2701182999Smav printf("No debugger in kernel\n"); 2702182999Smav#endif 2703182999Smav break; 2704187721Smav case LSH: 2705187721Smav shfts |= 1; 2706187721Smav break; 2707187721Smav case RSH: 2708187721Smav shfts |= 2; 2709187721Smav break; 2710182999Smav case LCTR: 2711182999Smav ctls |= 1; 2712187721Smav break; 2713182999Smav case RCTR: 2714182999Smav ctls |= 2; 2715182999Smav break; 2716182999Smav case LALT: 2717182999Smav alts |= 1; 2718182999Smav break; 2719182999Smav case RALT: 2720182999Smav alts |= 2; 2721182999Smav break; 2722182999Smav case ASH: 2723182999Smav agrs = 1; 2724182999Smav break; 2725182999Smav case META: 2726182999Smav metas = 1; 2727182999Smav break; 2728182999Smav case NEXT: 2729182999Smav switch_scr(cur_console, 2730182999Smav (get_scr_num() + 1) % MAXCONS); 2731182999Smav break; 2732182999Smav case BTAB: 2733182999Smav action = F(16); 2734182999Smav default: 2735182999Smav if (action >= F_SCR && action <= L_SCR) { 2736182999Smav switch_scr(cur_console, action - F_SCR); 2737182999Smav break; 2738182999Smav } 2739182999Smav if (action >= F_FN && action <= L_FN) 2740182999Smav action |= FKEY; 2741182999Smav return(action); 2742182999Smav } 2743182999Smav } 2744182999Smav else { 2745182999Smav if (metas) 2746182999Smav action |= MKEY; 2747162922Sariff return(action); 2748162922Sariff } 2749162922Sariff } 2750162922Sariff goto next_code; 2751162922Sariff} 2752162922Sariff 2753162922Sariffint 2754162922Sariffgetchar(void) 2755162922Sariff{ 2756182999Smav u_char thechar; 2757182999Smav int s; 2758162922Sariff 2759162922Sariff polling = 1; 2760162922Sariff s = splhigh(); 2761162922Sariff scput('>'); 2762162922Sariff thechar = (u_char) scgetc(0); 2763162922Sariff polling = 0; 2764162922Sariff splx(s); 2765162922Sariff switch (thechar) { 2766162922Sariff default: 2767162922Sariff if (thechar >= scr_map[0x20]) 2768162922Sariff scput(thechar); 2769162922Sariff return(thechar); 2770162922Sariff case cr: 2771162922Sariff case lf: 2772162922Sariff scput(cr); scput(lf); 2773162922Sariff return(lf); 2774162922Sariff case bs: 2775162922Sariff case del: 2776162922Sariff scput(bs); scput(scr_map[0x20]); scput(bs); 2777162922Sariff return(thechar); 2778162922Sariff case cntld: 2779162922Sariff scput('^'); scput('D'); scput('\r'); scput('\n'); 2780162922Sariff return(0); 2781162922Sariff } 2782162922Sariff} 2783162922Sariff 2784162922Sariffint 2785162922Sariffpcmmap(dev_t dev, int offset, int nprot) 2786162922Sariff{ 2787162922Sariff if (offset > 0x20000 - PAGE_SIZE) 2788162922Sariff return -1; 2789162922Sariff return i386_btop((VIDEOMEM + offset)); 2790162922Sariff} 2791162922Sariff 2792162922Sariffstatic void 2793162922Sariffkbd_wait(void) 2794162922Sariff{ 2795162922Sariff int i = 1000; 2796162922Sariff 2797162922Sariff while (i--) { 2798162922Sariff if ((inb(KB_STAT) & KB_READY) == 0) 2799162922Sariff break; 2800162922Sariff DELAY (10); 2801162922Sariff } 2802162922Sariff} 2803162922Sariff 2804162922Sariffstatic void 2805162922Sariffkbd_cmd(u_char command) 2806162922Sariff{ 2807162922Sariff int retry = 5; 2808162922Sariff do { 2809162922Sariff int i = 100000; 2810162922Sariff 2811162922Sariff kbd_wait(); 2812162922Sariff#if ASYNCH 2813162922Sariff kbd_reply = 0; 2814162922Sariff outb(KB_DATA, command); 2815162922Sariff while (i--) { 2816162922Sariff if (kbd_reply == KB_ACK) 2817162922Sariff return; 2818162922Sariff if (kbd_reply == KB_RESEND) 2819162922Sariff break; 2820162922Sariff } 2821162922Sariff#else 2822162922Sariff outb(KB_DATA, command); 2823162922Sariff while (i--) { 2824162922Sariff if (inb(KB_STAT) & KB_BUF_FULL) { 2825162922Sariff int val; 2826162922Sariff DELAY(10); 2827162922Sariff val = inb(KB_DATA); 2828162922Sariff if (val == KB_ACK) 2829162922Sariff return; 2830162922Sariff if (val == KB_RESEND) 2831162922Sariff break; 2832162922Sariff } 2833162922Sariff } 2834162922Sariff#endif 2835162922Sariff } while (retry--); 2836162922Sariff} 2837162922Sariff 2838162922Sariffstatic void 2839162922Sariffset_mode(scr_stat *scp) 2840162922Sariff{ 2841162922Sariff char *modetable; 2842162922Sariff char special_modetable[64]; 2843162922Sariff int mode, font_size; 2844162922Sariff 2845162922Sariff if (scp != cur_console) 2846162922Sariff return; 2847162922Sariff 2848162922Sariff /* setup video hardware for the given mode */ 2849162922Sariff switch (scp->mode) { 2850162922Sariff case M_VGA_M80x60: 2851162922Sariff bcopyw(video_mode_ptr+(64*M_VGA_M80x25),&special_modetable, 64); 2852162922Sariff special_modetable[2] = 8; 2853162922Sariff special_modetable[19] = 7; 2854162922Sariff special_modetable[16] = 0xdf; /* 480 lines */ 2855162922Sariff special_modetable[28] = 0xdf; /* 480 lines */ 2856162922Sariff modetable = special_modetable; 2857162922Sariff goto setup_mode; 2858162922Sariff 2859164614Sariff case M_VGA_C80x60: 2860164614Sariff bcopyw(video_mode_ptr+(64*M_VGA_C80x25),&special_modetable, 64); 2861164614Sariff special_modetable[2] = 8; 2862164614Sariff special_modetable[19] = 7; 2863164614Sariff special_modetable[16] = 0xdf; /* 480 lines */ 2864164614Sariff special_modetable[28] = 0xdf; /* 480 lines */ 2865171330Sariff modetable = special_modetable; 2866164614Sariff goto setup_mode; 2867164614Sariff 2868164614Sariff case M_VGA_M80x50: 2869169277Sariff bcopyw(video_mode_ptr+(64*M_VGA_M80x25),&special_modetable, 64); 2870169277Sariff special_modetable[2] = 8; 2871169277Sariff special_modetable[19] = 7; 2872169277Sariff modetable = special_modetable; 2873169277Sariff goto setup_mode; 2874164614Sariff 2875164614Sariff case M_VGA_C80x50: 2876164614Sariff bcopyw(video_mode_ptr+(64*M_VGA_C80x25),&special_modetable, 64); 2877164614Sariff special_modetable[2] = 8; 2878164614Sariff special_modetable[19] = 7; 2879164614Sariff modetable = special_modetable; 2880164614Sariff goto setup_mode; 2881164614Sariff 2882164614Sariff case M_ENH_B80x43: 2883164614Sariff bcopyw(video_mode_ptr+(64*M_ENH_B80x25),&special_modetable, 64); 2884164614Sariff special_modetable[2] = 8; 2885164614Sariff special_modetable[19] = 7; 2886164614Sariff special_modetable[28] = 87; 2887162922Sariff modetable = special_modetable; 2888164614Sariff goto setup_mode; 2889164614Sariff 2890164614Sariff case M_ENH_C80x43: 2891171141Sariff bcopyw(video_mode_ptr+(64*M_ENH_C80x25),&special_modetable, 64); 2892182999Smav special_modetable[2] = 8; 2893164614Sariff special_modetable[19] = 7; 2894164614Sariff special_modetable[28] = 87; 2895164614Sariff modetable = special_modetable; 2896164614Sariff goto setup_mode; 2897164614Sariff 2898182999Smav case M_VGA_M80x30: 2899164614Sariff bcopyw(video_mode_ptr+(64*M_VGA_M80x25),&special_modetable, 64); 2900164614Sariff special_modetable[16] = 0xdf; /* 480 lines */ 2901164614Sariff special_modetable[28] = 0xdf; /* 480 lines */ 2902164614Sariff modetable = special_modetable; 2903171141Sariff goto setup_mode; 2904182999Smav 2905182999Smav case M_VGA_C80x30: 2906182999Smav bcopyw(video_mode_ptr+(64*M_VGA_C80x25),&special_modetable, 64); 2907182999Smav special_modetable[16] = 0xdf; /* 480 lines */ 2908182999Smav special_modetable[28] = 0xdf; /* 480 lines */ 2909182999Smav modetable = special_modetable; 2910182999Smav goto setup_mode; 2911164614Sariff 2912164614Sariff case M_VGA_C40x25: case M_VGA_C80x25: /* VGA TEXT MODES */ 2913182999Smav case M_VGA_M80x25: 2914182999Smav case M_B40x25: case M_C40x25: 2915182999Smav case M_B80x25: case M_C80x25: 2916164614Sariff case M_ENH_B40x25: case M_ENH_C40x25: 2917164614Sariff case M_ENH_B80x25: case M_ENH_C80x25: 2918164614Sariff 2919182999Smav modetable = video_mode_ptr + (scp->mode * 64); 2920182999Smavsetup_mode: 2921182999Smav set_vgaregs(modetable); 2922182999Smav font_size = *(modetable + 2); 2923164614Sariff 2924164614Sariff /* set font type (size) */ 2925164614Sariff switch (font_size) { 2926164614Sariff case 0x08: 2927164614Sariff outb(TSIDX, 0x03); outb(TSREG, 0x05); /* font 1 */ 2928164614Sariff break; 2929164614Sariff case 0x0E: 2930164614Sariff outb(TSIDX, 0x03); outb(TSREG, 0x0A); /* font 2 */ 2931164614Sariff break; 2932164614Sariff case 0x10: 2933164614Sariff outb(TSIDX, 0x03); outb(TSREG, 0x00); /* font 0 */ 2934171141Sariff break; 2935164614Sariff default: 2936164614Sariff outb(TSIDX, 0x03); outb(TSREG, 0x05); /* font 1 */ 2937164614Sariff } 2938169277Sariff break; 2939164614Sariff 2940164614Sariff case M_BG320: case M_CG320: case M_BG640: 2941169277Sariff case M_CG320_D: case M_CG640_E: 2942164614Sariff case M_CG640x350: case M_ENH_CG640: 2943171141Sariff case M_BG640x480: case M_CG640x480: case M_VGA_CG320: 2944171141Sariff 2945164614Sariff set_vgaregs(video_mode_ptr + (scp->mode * 64)); 2946164614Sariff break; 2947164614Sariff 2948164614Sariff default: 2949164614Sariff /* call user defined function XXX */ 2950164614Sariff break; 2951164614Sariff } 2952164614Sariff 2953164614Sariff /* set border color for this (virtual) console */ 2954164614Sariff set_border(scp->border); 2955164614Sariff return; 2956164614Sariff} 2957164614Sariff 2958164614Sariffstatic void 2959164614Sariffset_border(int color) 2960164614Sariff{ 2961164614Sariff inb(crtc_addr+6); /* reset flip-flop */ 2962164614Sariff outb(ATC, 0x11); outb(ATC, color); 2963164614Sariff inb(crtc_addr+6); /* reset flip-flop */ 2964164614Sariff outb(ATC, 0x20); /* enable Palette */ 2965164614Sariff} 2966164614Sariff 2967164614Sariffstatic void 2968164614Sariffset_vgaregs(char *modetable) 2969164614Sariff{ 2970164614Sariff int i, s = splhigh(); 2971164614Sariff 2972164614Sariff outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */ 2973164614Sariff outb(TSIDX, 0x07); outb(TSREG, 0x00); /* unlock registers */ 2974164614Sariff for (i=0; i<4; i++) { /* program sequencer */ 2975164614Sariff outb(TSIDX, i+1); 2976164614Sariff outb(TSREG, modetable[i+5]); 2977164614Sariff } 2978164614Sariff outb(MISC, modetable[9]); /* set dot-clock */ 2979164614Sariff outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */ 2980164614Sariff outb(crtc_addr, 0x11); 2981164614Sariff outb(crtc_addr+1, inb(crtc_addr+1) & 0x7F); 2982164614Sariff for (i=0; i<25; i++) { /* program crtc */ 2983164614Sariff outb(crtc_addr, i); 2984164614Sariff if (i == 14 || i == 15) /* no hardware cursor */ 2985164614Sariff outb(crtc_addr+1, 0xff); 2986164614Sariff else 2987164614Sariff outb(crtc_addr+1, modetable[i+10]); 2988164614Sariff } 2989164614Sariff inb(crtc_addr+6); /* reset flip-flop */ 2990164614Sariff for (i=0; i<20; i++) { /* program attribute ctrl */ 2991164614Sariff outb(ATC, i); 2992164614Sariff outb(ATC, modetable[i+35]); 2993164614Sariff } 2994164614Sariff for (i=0; i<9; i++) { /* program graph data ctrl */ 2995164614Sariff outb(GDCIDX, i); 2996164614Sariff outb(GDCREG, modetable[i+55]); 2997164614Sariff } 2998166796Sariff inb(crtc_addr+6); /* reset flip-flop */ 2999164614Sariff outb(ATC ,0x20); /* enable palette */ 3000169277Sariff splx(s); 3001164614Sariff} 3002164614Sariff 3003164614Sariffstatic void 3004171141Sariffcopy_font(int direction, int segment, int size, char* font) 3005171141Sariff{ 3006169277Sariff int ch, line, s; 3007164614Sariff u_char val; 3008164614Sariff 3009164614Sariff outb(TSIDX, 0x01); val = inb(TSREG); /* blank screen */ 3010164614Sariff outb(TSIDX, 0x01); outb(TSREG, val | 0x20); 3011182999Smav 3012182999Smav /* setup vga for loading fonts (graphics plane mode) */ 3013182999Smav inb(crtc_addr+6); /* reset flip/flop */ 3014182999Smav outb(ATC, 0x30); outb(ATC, 0x01); 3015182999Smav outb(TSIDX, 0x02); outb(TSREG, 0x04); 3016182999Smav outb(TSIDX, 0x04); outb(TSREG, 0x06); 3017182999Smav outb(GDCIDX, 0x04); outb(GDCREG, 0x02); 3018182999Smav outb(GDCIDX, 0x05); outb(GDCREG, 0x00); 3019182999Smav outb(GDCIDX, 0x06); outb(GDCREG, 0x05); /* addr = a0000, 64kb */ 3020182999Smav for (ch=0; ch < 256; ch++) 3021193640Sariff for (line=0; line < size; line++) 3022182999Smav if (direction) 3023182999Smav *(char *)pa_to_va(VIDEOMEM+(segment*0x4000)+(ch*32)+line) = 3024182999Smav font[(ch*size)+line]; 3025182999Smav else 3026182999Smav font[(ch*size)+line] = 3027182999Smav *(char *)pa_to_va(VIDEOMEM+(segment*0x4000)+(ch*32)+line); 3028182999Smav /* setup vga for text mode again */ 3029182999Smav s = splhigh(); 3030182999Smav inb(crtc_addr+6); /* reset flip/flop */ 3031182999Smav outb(ATC, 0x30); outb(ATC, 0x0C); 3032182999Smav outb(TSIDX, 0x02); outb(TSREG, 0x03); 3033182999Smav outb(TSIDX, 0x04); outb(TSREG, 0x02); 3034182999Smav outb(GDCIDX, 0x04); outb(GDCREG, 0x00); 3035182999Smav outb(GDCIDX, 0x05); outb(GDCREG, 0x10); 3036182999Smav if (crtc_addr == MONO_BASE) { 3037182999Smav outb(GDCIDX, 0x06); outb(GDCREG, 0x0A); /* addr = b0000, 32kb */ 3038182999Smav } 3039182999Smav else { 3040182999Smav outb(GDCIDX, 0x06); outb(GDCREG, 0x0E); /* addr = b8000, 32kb */ 3041182999Smav } 3042182999Smav splx(s); 3043182999Smav outb(TSIDX, 0x01); val = inb(TSREG); /* unblank screen */ 3044182999Smav outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); 3045182999Smav} 3046182999Smav 3047182999Smavstatic void 3048182999Smavsave_palette(void) 3049162922Sariff{ 3050162922Sariff int i; 3051162922Sariff 3052162922Sariff outb(PALRADR, 0x00); 3053162922Sariff for (i=0x00; i<0x300; i++) 3054162922Sariff palette[i] = inb(PALDATA); 3055162922Sariff inb(crtc_addr+6); /* reset flip/flop */ 3056162922Sariff} 3057162922Sariff 3058162922Sariffstatic void 3059171330Sariffload_palette(void) 3060164614Sariff{ 3061182999Smav int i; 3062182999Smav 3063164614Sariff outb(PIXMASK, 0xFF); /* no pixelmask */ 3064182999Smav outb(PALWADR, 0x00); 3065182999Smav for (i=0x00; i<0x300; i++) 3066182999Smav outb(PALDATA, palette[i]); 3067162922Sariff inb(crtc_addr+6); /* reset flip/flop */ 3068162922Sariff outb(ATC, 0x20); /* enable palette */ 3069162922Sariff} 3070162922Sariff 3071162922Sariffstatic void 3072162922Sariffdo_bell(scr_stat *scp, int pitch, int duration) 3073162922Sariff{ 3074162922Sariff if (scp == cur_console) { 3075182999Smav if (configuration & VISUAL_BELL) { 3076162922Sariff if (blink_in_progress) 3077182999Smav return; 3078182999Smav undraw_cursor(scp); 3079182999Smav bcopy(scp->crt_base, scp->scr_buf, 3080182999Smav scp->xsize * scp->ysize * sizeof(u_short)); 3081182999Smav blink_in_progress = 4; 3082182999Smav timeout((timeout_func_t)blink_screen, scp, hz/10); 3083182999Smav } 3084182999Smav else 3085182999Smav sysbeep(pitch, duration); 3086182999Smav } 3087162922Sariff} 3088162922Sariff 3089162922Sariffstatic void 3090162922Sariffblink_screen(scr_stat *scp) 3091162922Sariff{ 3092162922Sariff if (blink_in_progress > 1) { 3093162922Sariff if (blink_in_progress & 1) 3094162922Sariff fillw(kernel_default.std_attr | scr_map[0x20], 3095162922Sariff scp->crt_base, scp->xsize * scp->ysize); 3096162922Sariff else 3097162922Sariff fillw(kernel_default.rev_attr | scr_map[0x20], 3098162922Sariff scp->crt_base, scp->xsize * scp->ysize); 3099162922Sariff blink_in_progress--; 3100162922Sariff timeout((timeout_func_t)blink_screen, scp, hz/10); 3101162922Sariff } 3102162922Sariff else { 3103162922Sariff bcopy(scp->scr_buf, scp->crt_base, 3104162922Sariff scp->xsize * scp->ysize * sizeof(u_short)); 3105162922Sariff draw_cursor(scp); 3106162922Sariff blink_in_progress = 0; 3107162922Sariff } 3108162922Sariff} 3109162922Sariff 3110162922Sariff#endif /* NSC */ 3111162922Sariff