⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 console.c

📁 一个开源著名的TDE编辑器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * All video and keyboard functions were gathered into one file. * * In version 3.2, this file was split into 3 sections:  1) unix curses * made to look and feel like a PC, 2) our PC hardware specific stuff, * and 3) hardware independent stuff. * * This file contains the keyboard and video i/o stuff.  Most of this stuff * is specific to the PC hardware, but it should be easily modified when * porting to other platforms.  With a few key functions written in * assembly, we have fairly fast video performance and good keyboard control. * Incidentally, the commented C code in the functions perform the same * function as the assembly code.  In earlier versions of TDE, I didn't * update the commented C code when I changed the assembly code.  The * C and assembly should be equivalent in version 2.2. * * Although using a curses type package would be more portable, curses * can be slow on PCs.  Let's keep our video and keyboard routines in * assembly.  I feel the need for speed. * * Being that TDE 2.2 keeps an accurate count of characters in each line, we * can allow the user to enter any ASCII or Extended ASCII key. * * Determining the video adapter type on the PC requires a function.  In *  TDE, that function is: * *                void video_config( struct vcfg *cfg ) * * video_config( ) is based on Appendix C in _Programmer's Guide to *  PC & PS/2 Video Systems_ by Richard Wilton. * * See: * *   Richard Wilton, _Programmer's Guide to PC & PS/2 Video Systems_, *    Microsoft Press, Redmond, Washington, 1987, Appendix C, pp 511-521. *    ISBN 1-55615-103-9. * * * New editor name:  TDE, the Thomson-Davis Editor. * Author:           Frank Davis * Date:             June 5, 1991, version 1.0 * Date:             July 29, 1991, version 1.1 * Date:             October 5, 1991, version 1.2 * Date:             January 20, 1992, version 1.3 * Date:             February 17, 1992, version 1.4 * Date:             April 1, 1992, version 1.5 * Date:             June 5, 1992, version 2.0 * Date:             October 31, 1992, version 2.1 * Date:             April 1, 1993, version 2.2 * Date:             June 5, 1993, version 3.0 * Date:             August 29, 1993 version 3.1 * Date:             November 13, version 3.2 * Date:             June 5, 1994, version 4.0 * Date:             December 5, 1998, version 5.0 (jmh) * * This code is released into the public domain, Frank Davis. * You may distribute it freely. */#include "tdestr.h"#include "common.h"#include "define.h"#include "tdefunc.h"#define __dj_include_pc_h_      /* don't include pc.h and its getkey */#include <bios.h>               /* for direct BIOS keyboard input */#include <sys/movedata.h>       /* for reading the BIOS memory */#include <inlines/pc.h>         /* for inportb to access the keyboard */#include <sys/exceptn.h>static unsigned long display_address;   /* address of display memory */static int  s_cbrk;             /* original control-break checking flag */static int  stdoutput;          /* stdout for redirected shelling */static int  kbd_active = TRUE;          /* should my INT09 be used? */volatilestatic unsigned int  kbd_shift = 0;     /* the actual shift states */static unsigned char kbd_bios_shift,    /* the fake BIOS shift states */                     kbd_scancode,      /* the hardware scan code */                     kbd_prefix = 0,    /* detect prefixed codes */                     kbd_menu;          /* the Menu key */static _go32_dpmi_seginfo kbd_old_int;  /* the original INT09 */static _go32_dpmi_seginfo kbd_new_int;  /* my new INT09 */#define KBD_INT (_go32_info_block.master_interrupt_controller_base + 1)/* * Convert a row and column co-ordinate into a screen memory address. */#define SCREEN_PTR( row, col ) \   (display_address + ((row) * g_display.ncols + (col)) * 2)static void bright_background( void );static int  shadow_width( int, int, int );static void kbd_int( void );/* * Name:    console_init * Purpose: initialise the console (video and keyboard) * Author:  Jason Hood * Date:    October 23, 2002 * Passed:  cfg:  pointer to hold video config data * Notes:   initialises both video and keyboard hardware. *          moved some stuff from main.c into here. */void console_init( struct vcfg *cfg ){   /*    * May as well make use of additional video memory.  There may be a    * problem with hi-res text modes (greater than 100x80, 132x61), but    * since I've been using page 1 since 5.0 without complaints, I guess    * it's not a problem, after all. (Whilst I can set 132x66, I never do,    * at least not for any period of time. :) )    */   page( 1 );   video_config( cfg );   __djgpp_set_ctrl_c( 0 );             /* turn off Ctrl-C breaking */   s_cbrk = getcbrk( );                 /* disable DOS Ctrl-Break checking */   setcbrk( 0 );   /*    * Setup and install the keyboard hardware interrupt.    *    * The method of finding the length of a function by defining another    * function after it doesn't work in newer GCCs (functions get reordered),    * so just use GDB to disassemble it and find its length that way.    */   _go32_dpmi_lock_code( kbd_int, 428 );   _go32_dpmi_lock_data( (void *)&kbd_shift, sizeof(kbd_shift) );   _go32_dpmi_lock_data( (void *)&kbd_bios_shift, sizeof(kbd_bios_shift) );   _go32_dpmi_lock_data( (void *)&kbd_scancode, sizeof(kbd_scancode) );   _go32_dpmi_lock_data( (void *)&kbd_prefix, sizeof(kbd_prefix) );   _go32_dpmi_get_protected_mode_interrupt_vector( KBD_INT, &kbd_old_int );   kbd_new_int.pm_selector = _go32_my_cs();   kbd_new_int.pm_offset = (unsigned long)kbd_int;   _go32_dpmi_chain_protected_mode_interrupt_vector( KBD_INT, &kbd_new_int );}/* * Name:    console_suspend * Purpose: temporarily shutdown the console * Author:  Jason Hood * Date:    October 23, 2002 * Notes:   readies the console for a shell */void console_suspend( void ){   page( 0 );   set_cursor_size( g_display.curses_cursor );   if (g_display.adapter != MDA)      set_overscan_color( g_display.old_overscan );   kbd_active = FALSE;   setcbrk( s_cbrk );   /*    * If output has been redirected then put it back to the screen for the    * shell and restore it afterwards.    */   if (g_status.output_redir) {      stdoutput = dup( fileno( stdout ) );      freopen( STDFILE, "w", stdout );   }   __djgpp_exception_toggle( );}/* * Name:    console_resume * Purpose: restore the console * Author:  Jason Hood * Date:    October 23, 2002 * Notes:   restores the console for TDE */void console_resume( int pause ){   __djgpp_exception_toggle( );   if (g_status.output_redir)      dup2( stdoutput, fileno( stdout ) );   kbd_active = TRUE;   kbd_shift = 0;   setcbrk( 0 );   if (pause)      getkey( );   page( 1 );   bright_background( );   if (g_display.adapter != MDA)      set_overscan_color( Color( Overscan ) );}/* * Name:    console_exit * Purpose: resets the console * Author:  Jason Hood * Date:    October 23, 2002 * Notes:   resets the console after TDE has finished */void console_exit( void ){   setcbrk( s_cbrk );   /*    * reset the cursor size and unload the keyboard utility    */   set_cursor_size( g_display.curses_cursor );   _go32_dpmi_set_protected_mode_interrupt_vector( KBD_INT, &kbd_old_int );   page( 0 );                   /* back to page 0 for DOS */}/* *   BIOS Data Areas * *   See: * *      IBM Corp., _Technical Reference:  Personal Computer AT_, *      Boca Raton, Florida, 1984, IBM part no. 1502494, *      pp 5-29 thru 5-32. * *  These addresses, variable names, types, and descriptions are directly *   from the IBM AT Technical Reference manual, BIOS listing, copyright IBM. * *   Address  Name           Type   Description *   0x0449   CRT_MODE       Byte   Current CRT mode *   0x044a   CRT_COLS       Word   Number columns on screen *   0x044c   CRT_LEN        Word   length of regen buffer, video buffer, bytes *   0x044e   CRT_START      Word   Starting address of regen buffer *   0x0450   CURSOR_POSN    Word   cursor for each of up to 8 pages. *   0x0460   CURSOR_MODE    Word   current cursor mode setting. *   0x0462   ACTIVE_PAGE    Byte   Current page *   0x0463   ADDR_6845      Word   base address for active display card *   0x0465   CRT_MODE_SET   Byte   current mode of display card *   0x0466   CRT_PALETTE    Byte   overscan color for CGA, EGA, and VGA. *   0x0467   io_rom_init    Word   Pointer to optional i/o rom init routine *   0x0469   io_rom_seg     Word   Pointer to io rom segment *   0x046b   intr_flag      Byte   Flag to indicate an interrupt happened *   0x046c   timer_low      Word   Low word of timer count *   0x046e   timer_high     Word   High word of timer count *   0x0470   timer_ofl      Byte   Timer has rolled over since last count *   0x0471   bios_break     Byte   Bit 7 = 1 if Break Key has been hit *   0x0472   reset_flag     Word   Word = 1234h if keyboard reset underway *   0x0484   ROWS           Byte   Number of displayed character rows - 1 *   0x0485   POINTS         Word   Height of character matrix *   0x0487   INFO           Byte   EGA and VGA display data *   0x0488   INFO_3         Byte   Configuration switches for EGA and VGA *   0x0489   flags          Byte   Miscellaneous flags *   0x0496   kb_flag_3      Byte   Additional keyboard flag *   0x048A   DCC            Byte   Display Combination Code *   0x04A8   SAVE_PTR       Dword  Pointer to BIOS save area */void video_config( struct vcfg *cfg ){struct LOWMEMVID{   unsigned char  vidmode;              /* 0x449 */   unsigned short scrwid;               /* 0x44A */   unsigned short scrlen;               /* 0x44C */   unsigned short scroff;               /* 0x44E */   struct   LOCATE   {      unsigned char col;      unsigned char row;   } __attribute__ ((packed)) csrpos[8];/* 0x450 */   unsigned short csrsize;              /* 0x460 */   unsigned char  page;                 /* 0x462 */   unsigned short addr_6845;            /* 0x463 */   unsigned char  crt_mode_set;         /* 0x465 */   unsigned char  crt_palette;          /* 0x466 */   unsigned char  system_stuff[29];     /* 0x467 */   unsigned char  rows;                 /* 0x484 */   unsigned short points;               /* 0x485 */   unsigned char  ega_info;             /* 0x487 */   unsigned char  info_3;               /* 0x488 */   unsigned char  skip[13];             /* 0x489 */   unsigned char  kb_flag_3;            /* 0x496 */} __attribute__ ((packed)) vid;union REGS in, out;unsigned char temp, active_display;   /*    * Move system information into our video structure.    */   dosmemget( 0x449, sizeof( vid ), &vid );   /*    * this next code was contributed by Jim Derr <jim.derr@spacebbs.com>    * jmh 991024: slightly modified, since I moved it from hw_initialize().    */   cfg->cols = vid.scrwid;   cfg->rows = vid.rows + 1;   if (cfg->rows == 1)      cfg->rows = 25;   in.w.ax =  0x1a00;   int86( VIDEO_INT, &in, &out );   temp = out.h.al;   active_display = out.h.bl;   if (temp == 0x1a && (active_display == 7 || active_display == 8))      g_display.adapter = VGA;   else {      in.h.ah =  0x12;      in.h.bl =  0x10;      int86( VIDEO_INT, &in, &out );      if (out.h.bl != 0x10) {         /* EGA */         if (vid.ega_info & 0x08)            g_display.adapter = vid.addr_6845 == 0x3d4 ? CGA : MDA;         else            g_display.adapter = EGA;      } else if (vid.addr_6845 == 0x3d4)         g_display.adapter = CGA;      else         g_display.adapter = MDA;   }   /*    * jmh 990213: Due to the config file being read after the cursor style    *             variable, just set cursor sizes.    */   if (g_display.adapter == CGA || g_display.adapter == EGA) {      g_display.cursor[SMALL_CURSOR]  = 0x0607;      g_display.cursor[MEDIUM_CURSOR] = 0x0407;      g_display.cursor[LARGE_CURSOR]  = 0x0007;   } else {      g_display.cursor[SMALL_CURSOR]  = 0x0b0c;      g_display.cursor[MEDIUM_CURSOR] = 0x070b;      g_display.cursor[LARGE_CURSOR]  = 0x000b;   }   /*    * jmh 990213: remember original cursor size.    */   g_display.curses_cursor = vid.csrsize;   /* jmh - added the vid.scroff for proper page offset */   display_address = 0xb8000ul + vid.scroff;   cfg->color = (vid.addr_6845 == 0x3D4);   if (!cfg->color)      display_address -= 0x8000;        /* monochrome is at 0xb0000 */   /*    * let's save the overscan color    */   g_display.old_overscan = vid.crt_palette;   /*    * Get keyboard type.  Since there is no interrupt that determines    * keyboard type, use this method.  Look at bit 4 in keyboard flag3.    * This method is not always foolproof on clones.    */   if ((vid.kb_flag_3 & 0x10) != 0)      mode.enh_kbd = TRUE;   else      mode.enh_kbd = FALSE;   /*    * jmh 991023: determine the width of the right edge of the shadow.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -