home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-10-05 | 33.2 KB | 1,064 lines |
- /******************* start of original comments ********************/
- /*
- * Written by Douglas Thomson (1989/1990)
- *
- * This source code is released into the public domain.
- */
-
- /*
- * Name: dte - Doug's Text Editor program - hardware dependent module
- * Purpose: This file contains all the code that needs to be different on
- * different hardware.
- * File: hwibm.c
- * Author: Douglas Thomson
- * System: This particular version is for the IBM PC and close compatibles.
- * It write directly to video RAM, so it is faster than other
- * techniques, but will cause "snow" on most CGA cards. See the
- * file "hwibmcga.c" for a version that avoids snow.
- * The compiler is Turbo C 2.0, using one of the large data memory
- * models.
- * Date: October 10, 1989
- * Notes: This module has been kept as small as possible, to facilitate
- * porting between different systems.
- */
- /********************* end of original comments ********************/
-
-
- /*
- * These routines were rewritten for Microsoft C. They are pretty much system
- * dependent and pretty much Microsoft C dependent. I also renamed this file
- * "main.c" - easier to find the main function.
- *
- * New editor name: tde, the Thomson-Davis Editor.
- * Author: Frank Davis
- * Date: June 5, 1991
- *
- * This modification of Douglas Thomson's code is released into the
- * public domain, Frank Davis. You may distribute it freely.
- */
-
- char *greatest_composer_ever = "W. A. Mozart, 1756-1791";
-
- #include "tdestr.h" /* tde types */
- #include "common.h"
- #include "define.h"
- #include "default.h"
- #include "help.h"
- #include "tdefunc.h"
- #include <dos.h> /* for renaming files */
- #ifdef __TURBOC__
- #include <dir.h> /* for searching the current path */
- #endif
- #include <bios.h> /* for direct BIOS keyboard input */
- #if defined( __TURBOC__ )
- #include <alloc.h> /* for memory allocation */
- #elif defined( __MSC__ )
- #include <malloc.h> /* for memory allocation */
- #endif
- #include <io.h> /* for file attribute code */
- #include <fcntl.h> /* open flags */
- #if defined( __MSC__ )
- #include <bios.h>
- #include <errno.h>
- #include <sys\types.h> /* S_IWRITE etc */
- #endif
- #include <sys\stat.h> /* S_IWRITE etc */
-
- #if defined( __MSC__ )
- void (interrupt far *old_control_c)( void ); /* variable for old CNTL-C */
- #endif
-
- int full_screen_buffer[2000]; /* 25 lines * 80 columns = 2000 characters */
- /* (make it an int for the attribute) */
-
-
- /*
- * Default color settings. Incidentally, I'm color blind (mild red-green) and
- * the default colors look fine to me.
- */
- static int colors[2][8] = {
- { HERC_REVERSE, HERC_NORMAL, HERC_REVERSE, HERC_REVERSE, HERC_HIGH,
- HERC_NORMAL, HERC_NORMAL, HERC_HIGH },
- { COLOR_HEAD, COLOR_TEXT, COLOR_MODE, COLOR_BLOCK, COLOR_MESSAGE,
- COLOR_HELP, COLOR_DIAG, COLOR_EOF }
- };
-
-
- /*
- * original control-break checking flag
- */
- static int s_cbrk;
-
- /*
- * Name: main
- * Purpose: To do any system dependent command line argument processing,
- * and then call the main editor function.
- * Date: October 10, 1989
- * Passed: argc: number of command line arguments
- * argv: text of command line arguments
- */
- void main( int argc, char *argv[] )
- {
- #if defined( __MSC__ )
- union REGS inregs, outregs;
- #endif
-
- /*
- * trap control-break to make it harmless, and turn checking off
- */
- #if defined( __MSC__ )
- inregs.h.ah = 0x33;
- inregs.h.al = 0;
- intdos( &inregs, &outregs );
- s_cbrk = outregs.h.dl;
- old_control_c = _dos_getvect( 0x23 );
- _dos_setvect( 0x23, harmless );
- inregs.h.ah = 0x33;
- inregs.h.al = 1;
- inregs.h.dl = 0;
- intdos( &inregs, &outregs );
- #else
- s_cbrk = getcbrk( );
- ctrlbrk( harmless );
- setcbrk( 0 );
- #endif
-
- initialize( );
- editor( argc, argv );
- terminate( );
- }
-
-
- /*
- * Name: error
- * Purpose: To report an error, and usually make the user type <ESC> before
- * continuing.
- * Date: June 5, 1991
- * Passed: kind: an indication of how serious the error was:
- * WARNING: error, but editor can continue after <ESC>
- * FATAL: abort the editor!
- * line: line to display message
- * message: string to be printed
- * Notes: Show dummy the message and ask for <ESC> if needed.
- */
- void error( int kind, int line, char *message )
- {
- char buff[MAX_COLS+2]; /* somewhere to store error before printing */
- register int c; /* character entered by user to continue */
- int func;
- char line_buff[(MAX_COLS+2)*2]; /* buffer for char and attribute */
-
- /*
- * tell the user what kind of an error it is
- */
- switch (kind) {
- case FATAL:
- strcpy( buff, "Fatal error: " );
- break;
- case WARNING:
- strcpy( buff, "Warning: " );
- break;
- }
-
- /*
- * prepare the error message itself
- */
- strcat( buff, message );
-
- /*
- * tell the user how to continue editing if necessary
- */
- if (kind == WARNING)
- strcat( buff, ": type <ESC>" );
-
- /*
- * output the error message
- */
- save_screen_line( 0, line, line_buff );
- set_prompt( buff, line );
-
- if (kind == FATAL) {
- /*
- * no point in making the user type <ESC>, since the program is
- * about to abort anyway...
- */
- terminate( );
- exit( 1 );
- } else {
- /*
- * If necessary, force the user to acknowledge the error by
- * typing <ESC> (or ^U).
- * This prevents any extra commands the user has entered from
- * causing problems after an error may have made them inappropriate.
- */
-
- c = getkey( );
- func = getfunc( c );
-
- while (func != AbortCommand && c != ESC) {
- c = getkey( );
- func = getfunc( c );
- }
- }
- restore_screen_line( 0, line, line_buff );
- s_output( " ", g_display.mode_line, 63, g_display.mode_color );
- }
-
-
- /*
- * Name: harmless
- * Purpose: To process control-break by ignoring it, so that the editor is
- * not aborted.
- * Date: June 5, 1991
- */
- #if defined( __MSC__ )
- int interrupt far harmless( void )
- #else
- static int harmless(void)
- #endif
- {
- return( 1 ); /* ignore */
- }
-
-
- /*
- * Name: terminate
- * Purpose: To restore the terminal to a safe state prior to leaving the
- * editor.
- * Date: October 10, 1989
- */
- void terminate( void )
- {
- #if defined( __MSC__ )
- union REGS inregs, outregs;
- #endif
-
- /*
- * restore control-break checking
- */
- #if defined( __MSC__ )
- _dos_setvect( 0x23, old_control_c );
- inregs.h.ah = 0x33;
- inregs.h.al = 1;
- inregs.h.dl = s_cbrk;
- intdos( &inregs, &outregs );
- #else
- setcbrk( s_cbrk );
- #endif
-
- #if defined( __MSC__ )
- hfree( (void huge *)g_status.start_mem );
- #endif
-
- set_cursor_size( g_display.insert_cursor );
- if (mode.enh_kbd == FALSE)
- simulate_enh_kbd( 0 );
- }
-
- /*
- * Name: hw_initialize
- * Purpose: To initialize the display ready for editor use.
- * Date: June 5, 1991
- */
- void hw_initialize( void )
- {
- #if defined( __MSC__ )
- struct vcfg cfg;
- #else
- struct text_info buff; /* for discovering display type */
- #endif
- unsigned paragraphs;
- long space; /* amount of memory to use */
- register int *clr;
-
- /*
- * set up screen size
- */
- g_display.ncols = MAX_COLS;
- g_display.nlines = MAX_LINES - 1;
- g_display.mode_line = MAX_LINES;
- g_display.line_length = MAX_LINE_LENGTH;
-
- /*
- * work out what kind of display is in use, and set attributes and
- * display address accordingly. Note that this will only work with
- * close IBM compatibles.
- */
-
- video_config( &cfg );
- g_display.display_address = (char far *)cfg.videomem;
-
- /*
- * Use an integer pointer to go thru the color array for setting up the
- * various color fields.
- */
- if (cfg.color == FALSE)
- clr = &colors[0][0];
- else
- clr = &colors[1][0];
-
- g_display.head_color = *clr++;
- g_display.text_color = *clr++;
- g_display.mode_color = *clr++;
- g_display.block_color = *clr++;
- g_display.message_color = *clr++;
- g_display.help_color = *clr++;
- g_display.diag_color = *clr++;
- g_display.eof_color = *clr++;
-
- /*
- * all the available memory for the text buffer
- */
- #if defined( __MSC__ )
- _dos_allocmem( 0xffff, ¶graphs );
- /*
- * A paragraph is 16 bytes. Convert paragraphs to bytes by shifting left
- * 4 bits.
- */
- space = (long)paragraphs << 4;
-
- /*
- * if using Microsoft C, allocate all available memory. If debugging in
- * in QC 2.5, uncomment the next lines so the debugger will have some room.
- */
- /* if (space > 20000l)
- space = 20000l; */
- if (space <= 0)
- return;
- #else
- space = farcoreleft() - 30000L;
- #endif
-
- #if defined( __MSC__ )
- if ((g_status.start_mem = (text_ptr)halloc( space, sizeof( char ))) == NULL)
- error( FATAL, g_display.nlines, "out of memory???" );
- #else
- if ((g_status.start_mem = farmalloc(space)) == NULL)
- error( FATAL, g_display.nlines, "out of memory???" );
- #endif
- g_status.max_mem = addltop( space, g_status.start_mem );
- }
-
-
- /*
- * Video BIOS Data Areas
- * The BIOS routines maintain several dynamic variables in an area of
- * memory called the Video Display Data Area. The following contains a
- * summary of these variables' addresses, their symbolic names, and
- * their contents. All addresses are relative to the 0x0000h segment.
- * From the IBM Technical Reference and other sources.
- *
- * Address Name Type Description
- * 0x0449 CRT_MODE Byte Current BIOS video number
- * 0x044a CRT_COLS Word Number of displayed character columns
- * 0x044c CRT_LEN Word Size of video buffer in bytes
- * 0x044e CRT_START Word Offset of start of video buffer
- * 0x0450 CURSOR_POSN Word Array of eight words containing the cursor
- * position for each of eight possible
- * video pages. The high-order byte of
- * each word contains the character row,
- * the low-order byte the character column
- * 0x0460 CURSOR_MODE Word Starting and ending lines for alphanumeric
- * cursor. The high-order byte contains
- * the starting (top) line; the low-order
- * byte contains the ending (bottom) line
- * 0x0462 ACTIVE_PAGE Byte Currently displayed video page number
- * 0x0463 ADDR_6845 Word I/O port address of CRT Controller's
- * Address register (3B4h for mono;
- * 3D4h for color)
- * 0x0465 CRT_MODE_SET Byte Current value for Mode Control register
- * (3B8h on MDA, 3D8h on CGA). On the
- * EGA and VGA, the value emulates those
- * used on the MDA and CGA.
- * 0x0466 CRT_PALETTE Byte Current value for the CGA Color Select
- * register (3D9h). On the EGA and VGA,
- * the value emulates those used on the
- * MDA and CGA.
- * 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 )
- {
- #pragma pack( 1 ) /* Use pragma to force packing on byte boundaries. */
-
- struct LOWMEMVID
- {
- char vidmode; /* 0x449 */
- unsigned scrwid; /* 0x44A */
- unsigned scrlen; /* 0x44C */
- unsigned scroff; /* 0x44E */
- struct LOCATE
- {
- unsigned char col;
- unsigned char row;
- } csrpos[8]; /* 0x450 */
- struct CURSIZE
- {
- unsigned char end;
- unsigned char start;
- } csrsize; /* 0x460 */
- char page; /* 0x462 */
- unsigned addr_6845; /* 0x463 */
- char crt_mode_set; /* 0x465 */
- char crt_palette[30]; /* 0x466 */
- char rows; /* 0x484 */
- unsigned points; /* 0x485 */
- char ega_info; /* 0x487 */
- char info_3; /* 0x488 */
- char skip[13]; /* 0x489 */
- char kb_flag_3; /* 0x496 */
- } vid;
- struct LOWMEMVID _far *pvid = &vid;
- #pragma pack( ) /* revert to previously defined pack pragma. */
-
- union REGS in, out;
- unsigned char temp, active_display;
-
- /* Move system information into uninitialized structure variable. */
- movedata( 0, 0x449, FP_SEG( pvid ), FP_OFF( pvid ), sizeof( vid ) );
-
- cfg->rescan = FALSE;
- in.x.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) {
- if (vid.addr_6845 == 0x3d4)
- g_display.adapter = CGA;
- else
- g_display.adapter = MDA;
- } else
- g_display.adapter = EGA;
- } else if (vid.addr_6845 == 0x3d4)
- g_display.adapter = CGA;
- else
- g_display.adapter = MDA;
- }
-
- if (g_display.adapter == CGA || g_display.adapter == EGA) {
- if (g_display.adapter == CGA)
- cfg->rescan = TRUE;
- g_display.insert_cursor = 0x0607;
- g_display.overw_cursor = 0x0407;
- } else {
- g_display.insert_cursor = 0x0b0c;
- g_display.overw_cursor = 0x070b;
- }
-
- cfg->mode = vid.vidmode;
- if (vid.addr_6845 == 0x3D4) {
- cfg->color = TRUE;
- FP_SEG( cfg->videomem ) = 0xb800;
- } else {
- cfg->color = FALSE;
- FP_SEG( cfg->videomem ) = 0xb000;
- }
- FP_OFF( cfg->videomem ) = 0x0000;
-
- /*
- * Set up 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;
- if (mode.enh_kbd == FALSE)
- simulate_enh_kbd( 1 );
- }
-
-
- /*
- * Name: set_cursor_size
- * Purpose: To set cursor size according to insert mode.
- * Date: June 5, 1991
- * Passed: csize: desired cursor size
- * Notes: use the global display structures to set the cursor size
- */
- void set_cursor_size( int csize )
- {
- _asm {
- mov ah, 1 ; function 1 - set cursor size
- mov cx, WORD PTR csize ; get cursor size ch:cl == top:bot
- int VIDEO_INT ; video interrupt = 10h
- }
- }
-
-
- /*
- * Name: hw_move
- * Purpose: To move data from one place to another as efficiently as
- * possible.
- * Date: October 10, 1989
- * Passed: dest: where to copy to
- * source: where to copy from
- * number: number of bytes to copy
- * Notes: moves may be (usually will be) overlapped. Although we can
- * move up to 64k-1 bytes at once, we can safely move only
- * 0xfff0 bytes at one time. Let's try only 0xf000.
- */
- void hw_move( text_ptr dest, text_ptr source, long number )
- {
- unsigned long s, d;
-
- s = ptoul( source );
- d = ptoul( dest );
- if (number < 0)
- /*
- * this should never happen...
- */
- error( WARNING, g_display.nlines, "negative move - contact Frank Davis" );
- else if (s == d)
- /*
- * nothing to be done
- */
- ;
- else if (s > d) {
- while (number > 0xF000L) {
- dest = nptop( dest );
- source = nptop( source );
- _fmemmove( dest, source, 0xF000 );
- dest = addltop( 0xF000L, dest );
- source = addltop( 0xF000L, source );
- number -= 0xF000L;
- }
- dest = nptop( dest );
- source = nptop( source );
- _fmemmove( dest, source, (unsigned)number );
- } else {
- source = addltop( number, source );
- dest = addltop( number, dest );
- while (number > 0xF000L) {
- source = addltop( -0xF000L, source );
- source = nptop( source );
- dest = addltop( -0xF000L, dest );
- dest = nptop ( dest );
- _fmemmove( dest, source, 0xF000 );
- number -= 0xF000L;
- }
- source = addltop( -number, source );
- dest = addltop( -number, dest );
- source = nptop( source );
- dest = nptop ( dest );
- _fmemmove( dest, source, (unsigned)number );
- }
- }
-
- /*
- * Name: hw_fattrib
- * Purpose: To determine the current file attributes.
- * Date: October 17, 1989
- * Passed: name: name of file to be checked
- * Returns: current read/write/execute etc attributes of the file, or
- * ERROR if file did not exist etc.
- */
- int hw_fattrib( char *name )
- {
- register int rc;
-
- #if defined( __MSC__ )
- rc = access( name, EXIST );
- #else
- rc = _chmod( name, EXIST );
- #endif
- return( rc );
- }
-
- /*
- * Name: hw_unlink
- * Purpose: To delete a file, regardless of access modes.
- * Date: October 17, 1989
- * Passed: name: name of file to be removed
- * line: line to display message
- * Returns: OK if file could be removed
- * ERROR otherwise
- */
- int hw_unlink( char *name, int line )
- {
- int result;
- register int rc;
- char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute */
-
- rc = OK;
- #if defined( __MSC__ )
- if ((result = access( name, EXIST )) != -1 && errno != EACCES) {
- #else
- if ((result = _chmod( name, EXIST )) != -1 && (result & FA_RDONLY) != 0) {
- #endif
- /*
- * file cannot be written
- */
- save_screen_line( 0, line, line_buff );
- set_prompt( "File is write protected! Overwrite anyway? (y/n): ", line );
- if (get_yn( ) != A_YES)
- rc = ERROR;
- #if defined( __MSC__ )
- if (rc == OK && chmod( name, S_IWRITE ) == ERROR)
- rc = ERROR;
- #else
- if (rc == OK && _chmod( name, 1, 0 ) == ERROR)
- rc = ERROR;
- #endif
- restore_screen_line( 0, line, line_buff );
- }
- if (rc == OK)
- rc = unlink( name );
- return( rc );
- }
-
- /*
- * Name: write_file
- * Purpose: To write text to a file, eliminating trailing space on the
- * way.
- * Date: June 5, 1991
- * Passed: name: name of disk file or device
- * mode: fopen flags to be used in open
- * start: first character in text buffer
- * end: last character (+1) in text buffer
- * block: write a file or a marked block
- * Returns: OK, or ERROR if anything went wrong
- */
- int write_file( char *name, char *mode, text_ptr start, text_ptr end,
- int block )
- {
- FILE *fp; /* file to be written */
- int rc;
- char *p;
- int len;
- int bc, ec, last_c;
- file_infos *file;
- long lend;
- long number;
-
- rc = OK;
- if ((fp = fopen( name, mode )) == NULL)
- rc = ERROR;
- else {
- start = cpf( start );
- if (block == LINE || block == BOX) {
- if (g_status.marked_file == NULL)
- rc = ERROR;
- else if (block == BOX) {
- file = g_status.marked_file;
- bc = file->block_bc;
- ec = file->block_ec;
- last_c = ec + 1 - bc;
- }
- }
- p = g_status.line_buff;
- if (rc == OK) {
- if (block == BOX) {
- lend = ptoul( end );
- for (;ptoul( start ) <= lend && rc == OK;) {
- g_status.copied = FALSE;
- load_buff( p, start, bc, ec, BOX );
- *(p+last_c) = '\n';
- *(p+last_c+1) = CONTROL_Z;
- len = find_CONTROL_Z( p );
- if (fwrite( p, sizeof( char ), len, fp ) < len)
- rc = ERROR;
- start = find_next( start );
- if (start == NULL)
- start = end + 1;
- }
- g_status.copied = FALSE;
- } else {
- number = ptoul( end ) - ptoul( start );
- len = 0x0800;
- start = nptop( start );
- while (number > 0x0800L && rc != ERROR) {
- _fmemcpy( full_screen_buffer, start, len );
- if (fwrite( full_screen_buffer, sizeof(char), len, fp )< len)
- rc = ERROR;
- number -= 0x0800L;
- start += 0x0800;
- start = nptop( start );
- }
- /*
- * now less than 2k is left, so finish off the write
- */
- len = number;
- _fmemcpy( full_screen_buffer, start, len );
- if (fwrite( full_screen_buffer, sizeof( char ), len, fp ) < len)
- rc = ERROR;
- }
- if (rc != ERROR)
- rc = fclose( fp );
- }
- }
- return( rc );
- }
-
- /*
- * Name: hw_save
- * Purpose: To save text to a file, eliminating trailing space on the
- * way.
- * Date: November 11, 1989
- * Passed: name: name of disk file
- * start: first character in text buffer
- * end: last character (+1) in text buffer
- * block: type of block defined
- * Returns: OK, or ERROR if anything went wrong
- * Notes: Trailing space at the very end of the file is NOT removed,
- * so that a block write of a block of spaces will work.
- * No error messages are displayed here, so the caller must
- * both tell the user what is happening, and print an error
- * message if anything goes wrong.
- * This function is in the hardware dependent module because
- * some computers require non-standard open parameters...
- */
- int hw_save( char *name, text_ptr start, text_ptr end, int block )
- {
- return write_file( name, "w", start, end, block );
- }
-
- /*
- * Name: hw_append
- * Purpose: To append text to a file.
- * Date: November 11, 1989
- * Passed: name: name of disk file
- * start: first character in text buffer
- * end: last character (+1) in text buffer
- * block: type of defined block
- * Returns: OK, or ERROR if anything went wrong
- * Notes: No error messages are displayed here, so the caller must
- * both tell the user what is happening, and print an error
- * message if anything goes wrong.
- * This function is in the hardware dependent module because
- * some computers require non-standard open parameters...
- */
- int hw_append( char *name, text_ptr start, text_ptr end, int block )
- {
- return write_file( name, "a", start, end, block );
- }
-
- /*
- * Name: hw_load
- * Purpose: To load a file into the text buffer.
- * Date: November 11, 1989
- * Passed: name: name of disk file
- * start: first character in text buffer
- * limit: last available character in text buffer
- * end: last character of file in text buffer
- * line: line to display messages
- * Returns: OK, or ERROR if anything went wrong
- * Notes: All error messages are displayed here, so the caller should
- * neither tell the user what is happening, nor print an error
- * message if anything goes wrong.
- * This function is in the hardware dependent module because
- * some computers require non-standard open parameters...
- */
- int hw_load( char *name, text_ptr start, text_ptr limit, text_ptr *end,
- int line )
- {
- int fd; /* file being read */
- int length; /* number of bytes actually read */
- int rc;
- char buff[MAX_COLS+2];
- char line_buff[(MAX_COLS+2)*2]; /* buffer for char and attribute */
-
- /*
- * try reading the file
- */
- rc = OK;
- if ((fd = open( name, O_RDONLY )) == ERROR) {
- combine_strings( buff, "File '", name,"'not found or error loading file");
- save_screen_line( 0, line, line_buff );
- set_prompt( buff, line );
- getkey( );
- restore_screen_line( 0, line, line_buff );
- rc = ERROR;
- } else {
- /*
- * read the entire file, without going past end of buffer.
- * Note that this means a file that is within 1K of the limit
- * will not be accepted. length set to a number > 0 for first loop
- */
- limit = addltop( -1024, limit );
- start = cpf( start );
- for (length=1; rc == OK && length > 0;) {
- if (ptoul( start ) >= ptoul( limit )) {
- combine_strings( buff, "file '", name, "'too big" );
- error( WARNING, line, buff );
- rc = WARNING;
- } else {
- if ((length = read( fd, full_screen_buffer, 2048 )) == ERROR) {
- combine_strings( buff, "error reading file '", name, "'" );
- error( WARNING, line, buff );
- rc = ERROR;
- } else {
- _fmemcpy( start, full_screen_buffer, length );
- start = addltop( length, start );
- }
- start = cpf( start );
- }
- }
- if (rc != ERROR) {
- if (*(start-1) != '\n')
- *start++ = '\n';
- }
- /*
- * close the file and report the final character in the buffer
- */
- close( fd );
- *end = start;
- }
- return( rc );
- }
-
-
- /*
- * Name: get_help
- * Purpose: save the screen and display key definitions
- * Date: June 5, 1991
- * Notes: This routine is dependent on the length of the strings in the
- * help screen. To make it easy to load in a new help screen,
- * the strings are assumed to be 80 characters long followed by
- * the '\0' character. It is assumed each that string contains
- * exactly 81 characters.
- */
- void get_help( windows *window )
- {
- register char *help;
- register int line;
-
- xygoto( -1, -1 );
- _fmemcpy( full_screen_buffer, g_display.display_address, 4000 );
- help = help_screen[0];
- for (line=0; help != NULL; ) {
- s_output( help, line, 0, g_display.help_color );
- help = help_screen[++line];
- }
- line = getkey( );
- _fmemcpy( g_display.display_address, full_screen_buffer, 4000 );
- }
-
-
- /*
- * Name: show_credits
- * Purpose: display authors
- * Date: June 5, 1991
- */
- void show_credits( void )
- {
- register char *credit;
- int line;
-
- xygoto( -1, -1 );
- credit = credit_screen[0];
- for (line=0; credit != NULL; ) {
- s_output( credit, line+2, 11, g_display.text_color );
- credit = credit_screen[++line];
- }
- }
-
- /*
- * The next function was written by Tom Waters, twaters@nswc-wo.navy.mil and
- * modified extensively by Frank Davis.
- *
- * "I use ANSI.SYS to redefine a few of my function keys and this causes a
- * problem when getch() is used in a program. For example, instead of returning
- * 321 for the F7, I get the redefined string inserted in the text. So, instead
- * of using getch(), I use the following function ..."
- *
- * Tom, thanks for the info and solution. I'm sure your function will be
- * be appreciated by everyone with ANSI key defs, Frank.
- */
-
- /*
- * Name: getkey
- * Purpose: use bios to get keyboard input (getch has trouble w/ ANSI
- * redefined keys)
- * Date: July 2, 1991
- * Modified:July 12, 1991, Frank Davis - accept ALT-xxx keyboard entry
- * September 10, 1991, Frank Davis - add support for Ctrl+Up, etc...
- * Passed: None
- * Notes: Uses the BIOS to read the next keyboard character. Service
- * 0 is keyboard read. Service 0x10 is the extended keyboard read.
- * Test for a bunch of special cases. Allow the user to enter any
- * ASCII or Extended ASCII code as a normal text characters,
- * exceptions are 10, 13, and 26 (CR, LF, EOF).
- */
- int getkey( void )
- {
- unsigned key, scan, num_lock, control, shift;
- register unsigned lo;
-
- /*
- * _bios_keybrd == int 16. It returns the scan code in ah, hi part of key,
- * and the ascii key code in al, lo part of key. If the character was
- * entered via ALT-xxx, the scan code, hi part of key, is 0.
- */
- if (mode.enh_kbd) {
- key = _bios_keybrd( 0x10 );
- lo = _bios_keybrd( 0x12 );
- if ((key & 0x00ff) == 0x00e0)
- key = key & 0xff00;
- } else {
- key = _bios_keybrd( 0 );
- lo = _bios_keybrd( 2 );
- }
- num_lock = lo & 0x20;
- control = lo & 0x04;
- shift = lo & 0x03;
- scan = (key & 0xff00) >> 8;
- lo = key & 0X00FF;
- lo = (lo == 0) ? (scan | 0x100) : lo;
-
- /*
- * Pressing Control+BackSpace generates the 0x7f character. Instead of
- * 0x7f, make lo the ASCII backspace character. If anyone wants the
- * 0x7f character, then they can enter it via ALT+xxx.
- */
- if (scan == 14 && lo == 0x7f)
- lo = 8;
-
-
- if (lo < 32) {
-
- /*
- * My machine at home is sorta weird. On every machine that I've
- * tested at the awffice, the ALT-xxx combination returns 0 for the
- * scan byte and xxx for the ASCII code. My machine returns 184 (decimal)
- * as the scan code?!?!? I added the next two lines for my machine at
- * home. I wonder if someone forgot to zero out ah for Alt keypad entry
- * when they wrote my bios.
- */
- if (scan > 0x80)
- scan = 0;
-
- /*
- * If user enters ALT+010 or ALT+013 make this a return. CR and LF
- * are special characters and they need to be handled by the editor.
- */
- if (scan == 0 && (lo == 10 || lo == 13))
- lo = 425;
-
- /*
- * Separate the ESC key from the ^[ key. The scan code for the ESC
- * key is 1. Map this to a different index into the key function
- * array just in case someone wants to define ESC or ^[ to different
- * functions. BTW, ESC and ^[ return the same ASCII code, 27.
- *
- */
- else if (scan == 1) {
- if (shift)
- lo = 260;
- else if (control)
- lo = 261;
- else
- lo = 258;
- }
-
- /*
- * Scan code for Enter = 28. Separate the various Enter keys.
- */
- else if (scan == 28) {
- if (shift)
- lo = 263;
- else if (control)
- lo = 264;
- else
- lo = 262;
- }
-
- /*
- * Scan code for Backspace = 14. Separate the various BackSpace keys.
- */
- else if (scan == 14) {
- if (shift)
- lo = 266;
- else if (control)
- lo = 267;
- else
- lo = 265;
- }
-
- /*
- * Scan code for Tab = 15. Separate the tab key.
- */
- else if (scan == 15) {
- lo = 268;
- }
-
- /*
- * if scan code is not 0, then a Control+a thru z was pressed. Map
- * those keys to the WordStar commands. If the scan code is 0, let
- * all ASCII and Extended ASCII character get thru except 10, 13, and 26.
- */
- else if (scan > 0)
- lo += 430;
-
- /*
- * Do not allow control z to get thru. Code 256 is not assigned to
- * any function, see default.h for more info.
- */
- if (lo == 26)
- lo = 256;
-
- } else if (!num_lock) {
- switch (scan) {
- /*
- * scan code for grey - == 74. if num_lock is not toggled, assign it
- * to the scroll line up function.
- */
- case 74 :
- lo = 423;
- break;
-
- /*
- * scan code for grey + == 78. if num_lock is not toggled, assign it
- * to the scroll line down function. if shift grey + then stationary
- * scroll down.
- */
- case 78 :
- lo = 424;
- break;
- }
- }
- return( lo );
- }
-
-
- /*
- * Name: getfunc
- * Purpose: get the function assigned to key c
- * Date: July 11, 1991
- * Passed: c: key just pressed
- * Notes: key codes less than 256 or 0x100 are not assigned a function.
- * The codes in the range 0-255 are ASCII and extended ASCII chars.
- */
- int getfunc( int c )
- {
- unsigned rc;
-
- if (c < 256)
- rc = 0;
- else
- rc = key_func[c-256].func;
- return( rc );
- }