home *** CD-ROM | disk | FTP | other *** search
- /* pc_term.c - BIOS video calls for GNU info
- Copyright (C) 1990 Free Software Foundation, Inc.
- Thorsten Ohl <td12@ddagsi3.bitnet>, 1990
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $Header: e:/gnu/info/RCS/pc_term.c 0.6 90/10/26 20:26:20 tho Exp $
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include <conio.h>
- #include <dos.h>
-
- #include "pc_term.h"
-
- unsigned char term_normal_attrib = NORMAL_ATTRIB;
- unsigned char term_inverse_attrib = INVERSE_ATTRIB;
-
- /* Higher level functions. */
- void clrscr (void);
- void clreop (void);
- void clreol (void);
- void write_char (int c);
- void textattr (unsigned char attrib);
-
- /* Lowest level BIOS calls. */
- void set_cursor_position (unsigned char row, unsigned char col);
- void scroll_up_active_page (unsigned char lines, unsigned char attrib,
- unsigned char top_row, unsigned char left_col,
- unsigned char bot_row, unsigned char right_col);
-
-
- /* supplied by info.c */
- extern void clear_eop_slowly (void);
-
- /* Main switch */
-
- void
- do_term (int command)
- {
- if (command < 0400)
- /* A character. */
- write_char (command);
- else
- /* Something less trivial. */
- switch (command)
- {
- case terminal_ear_bell:
- putchar ('\a');
- break;
-
- case terminal_clearEOP:
- clreop ();
- break;
-
- case terminal_clearEOL:
- clreol ();
- break;
-
- case terminal_use_begin:
- case terminal_use_end:
- /* NOP */
- break;
-
- case terminal_inverse_begin:
- textattr (term_inverse_attrib);
- break;
-
- case terminal_end_attributes:
- textattr (term_normal_attrib);
- break;
-
- default:
- clrscr ();
- fprintf (stderr, "Internal error: Unknown terminal command.\n");
- exit (0);
- break;
- }
- }
-
- #ifdef USE_ASSEMBLER
-
- #define _ax ax
- #define _bx bx
- #define _cx cx
- #define _dx dx
- #define _si si
- #define _di di
-
- #define _cy
-
- #define _ah ah
- #define _al al
- #define _bh bh
- #define _bl bl
- #define _ch ch
- #define _cl cl
- #define _dh dh
- #define _dl dl
-
- #define _es es
- #define _cs cs
- #define _ss ss
- #define _ds ds
-
-
- /* Careful with semicolons here! */
-
- #define _byte byte ptr
- #define _alloc_regs
- #define _alloc_regs_x
- #define _push(reg) _asm push reg
- #define _pop(reg) _asm pop reg
- #define _mov(dest,source) _asm mov dest, source
- #define _mov_ax(dest,source) _asm mov ax, source _asm mov dest, ax
- #define _inc(reg) _asm inc reg
- #define _add(reg, n) _asm add reg, n
- #define _video(func) _asm mov ah, func _asm int 0x10
- #define _video_x _video
- #define _keybrd(func) _asm mov ah, func _asm int 0x16
-
- #else /* not USE_ASSEMBLER */
-
- #define _ax _regs.x.ax
- #define _bx _regs.x.bx
- #define _cx _regs.x.cx
- #define _dx _regs.x.dx
- #define _si _regs.x.si
- #define _di _regs.x.di
-
- #define _cy _regs.x.cflag
-
- #define _ah _regs.h.ah
- #define _al _regs.h.al
- #define _bh _regs.h.bh
- #define _bl _regs.h.bl
- #define _ch _regs.h.ch
- #define _cl _regs.h.cl
- #define _dh _regs.h.dh
- #define _dl _regs.h.dl
-
- #define _es _segregs.es
- #define _cs _segregs.cs
- #define _ss _segregs.ss
- #define _ds _segregs.ds
-
- #define _byte (unsigned char)
- #define _alloc_regs union REGS _regs
- #define _alloc_regs_x union REGS _regs; struct SREGS _segregs
- #define _push(reg)
- #define _pop(reg)
- #define _mov(dest,source) dest = source
- #define _mov_ax _mov
- #define _inc(reg) (reg)++
- #define _add(reg, n) (reg) += n;
- #define _video(func) _ah = func; int86 (0x10, &_regs, &_regs)
- #define _video_x(func) _ah = func; \
- int86x (0x10, &_regs, &_regs, &_segregs)
- #define _keybrd(func) _ah = func; int86 (0x16, &_regs, &_regs)
-
- #endif /* not USE_ASSEMBLER */
-
- /* Terminal paramters. */
-
- unsigned char term_attrib = 0x07;
- unsigned char term_top_row = 0x00;
- unsigned char term_left_col = 0x00;
- unsigned char term_bot_row = 0x24;
- unsigned char term_right_col = 0x79;
-
- int terminal_rows = 80; /* This should read `cols', Brian... */
- int terminal_lines = 25;
-
- #pragma pack(1)
- struct video_state_info
- {
- unsigned int off_static_tab; /* offset of static info table */
- unsigned int seg_static_tab; /* segment of static info table */
- unsigned char video_mode; /* videomode */
- unsigned int num_cols; /* */
- unsigned int regen_length; /* */
- unsigned int regen_offset; /* */
- unsigned int cursor_pos[8]; /* */
- unsigned int cursor_mode; /* */
- unsigned char active_page; /* */
- unsigned int crtc_address; /* */
- unsigned char reg_3x8; /* */
- unsigned char reg_3x9; /* */
- unsigned char num_rows; /* */
- unsigned int char_height; /* */
- unsigned char act_disp_cc; /* */
- unsigned char alt_disp_cc; /* */
- unsigned int num_colors; /* */
- unsigned char num_pages; /* */
- unsigned char scan_lines; /* */
- unsigned char prim_char_blk; /* */
- unsigned char sec_char_blk; /* */
- unsigned char misc_info; /* */
- unsigned char reserved_2e_30[3]; /* reserved bytes */
- unsigned char avl_memory; /* */
- unsigned char save_ptr_state; /* */
- unsigned char reserved_33_3f[13]; /* reserved bytes */
- };
- #pragma pack()
-
-
- /* Initialize screen output. Currently this just sets the screen
- dimensions. */
- void
- opsys_init_terminal (void)
- {
- #ifndef USE_ANSI
-
- unsigned int segm;
- unsigned int offs;
- char check;
- struct video_state_info _far *video_state
- = (struct video_state_info _far *)
- alloca (sizeof (struct video_state_info));
- _alloc_regs_x;
-
- if (!video_state)
- {
- fprintf (stderr, "Stack overflow.\n");
- abort ();
- }
-
- segm = FP_SEG (video_state);
- offs = FP_OFF (video_state);
-
- _mov (_bx, 0x00); /* "implementation type" (???) */
- _mov_ax (_es, segm);
- _mov (_di, offs);
-
- _video_x (0x1b); /* Return state information function */
- _mov (check, _al);
-
- if (check == 0x1b)
- {
- terminal_lines = video_state->num_rows;
- terminal_rows = (int) video_state->num_cols;
- }
- else
- {
- #if 0 /* shut up! (on public demand) */
- fprintf (stderr, "\aNot a VGA terminal, assuming 80x25 BW.\n");
- #endif
- term_normal_attrib = FG_BG (WHITE, BLACK);
- term_inverse_attrib = FG_BG (BLACK, WHITE);
- }
-
- term_attrib = term_normal_attrib;
-
- term_top_row = 0x00;
- term_left_col = 0x00;
- term_bot_row = (unsigned char) (terminal_lines - 1);
- term_right_col = (unsigned char) (terminal_rows - 1);
-
- #endif /* not USE_ANSI */
-
- clrscr ();
- }
-
-
- /* Write the character C, using TERM_ATTRIB as attribute, and step one
- column right. */
-
- void
- write_char (int c)
- {
- #ifndef USE_ANSI
- _alloc_regs;
-
- _video (0x0f); /* Get active page into _bh. */
-
- _mov (_al, _byte c); /* The character to write. */
- _mov (_cx, 0x01); /* Write it once. */
- _mov (_bl, term_attrib); /* With current attribute. */
- _video (0x09);
-
- _video (0x03); /* Read character position function. */
- _inc (_dl); /* increment column */
- _video (0x02); /* Set character position function. */
-
- #else /* USE_ANSI */
-
- putchar (c);
-
- #endif /* USE_ANSI */
- }
-
-
- /* Move the cursor to X, Y */
-
- void
- opsys_goto_pos (int x, int y)
- {
- #ifndef USE_ANSI
- set_cursor_position ((unsigned char) y, (unsigned char) x);
- #else
- printf ("\033[%d;%dH", y, x);
- #endif
- }
-
-
- /* Clear the screen. */
-
- void
- clrscr (void)
- {
- #ifndef USE_ANSI
- scroll_up_active_page (0, term_attrib, term_top_row, term_left_col,
- term_bot_row, term_right_col);
- #else /* USE_ANSI */
- fputs ("\033[2j", stdout);
- #endif /* USE_ANSI */
- }
-
-
- /* Clear from the cursor to the end of screen. */
-
- void
- clreop (void)
- {
- #ifndef USE_ANSI
-
- unsigned char row;
- _alloc_regs;
-
- _video (0x0f); /* Get active page into _bh */
- _video (0x03); /* Read character position function. */
- _inc (_dh);
- _mov (row, _dh); /* row from which to blank */
-
- clreol ();
- scroll_up_active_page (0, term_attrib, row, term_left_col,
- term_bot_row, term_right_col);
-
- #else /* USE_ANSI */
-
- clear_eop_slowly ();
-
- #endif /* USE_ANSI */
- }
-
-
- /* Clear from the cursor to the end of the cursor's line. */
-
- void
- clreol (void)
- {
- #ifndef USE_ANSI
-
- int col = 0;
- _alloc_regs;
-
- _video (0x0f); /* Get active page into _bh */
- _video (0x03); /* Read character position function. */
-
- _mov (col, _dl);
-
- col = term_right_col - col + 1;
- _mov (_cx, col);
-
- _mov (_al, ' ');
- _mov (_bl, term_attrib);
- _video (0x09); /* Write characters at cursor position. */
-
- #else /* USE_ANSI */
-
- fputs ("\033[K", stdout);
-
- #endif /* USE_ANSI */
- }
-
-
- void
- set_cursor_position (unsigned char row, unsigned char col)
- {
- _alloc_regs;
-
- _video (0x0f); /* Get active page into _bh */
- _mov (_dh, row);
- _mov (_dl, col);
- _video (0x02); /* set cursor position function */
- }
-
-
- void
- scroll_up_active_page (unsigned char lines, unsigned char attrib,
- unsigned char top_row, unsigned char left_col,
- unsigned char bot_row, unsigned char right_col)
- {
- _alloc_regs;
-
- _mov (_al, lines);
- _mov (_bh, attrib);
- _mov (_cl, left_col);
- _mov (_ch, top_row);
- _mov (_dl, right_col);
- _mov (_dh, bot_row);
-
- _video (0x06);
- }
-
-
- void
- textattr (unsigned char attrib)
- {
- #ifndef USE_ANSI
-
- term_attrib = attrib;
-
- #else /* USE_ANSI */
-
- if (attrib == INVERSE_ATTRIB)
- fputs ("\033[7m", stdout);
- else
- fputs ("\033[0m", stdout);
-
- #endif /* USE_ANSI */
- }
-
-
- /* Get a character. */
-
- int
- pc_getc (void)
- {
- int c = getch ();
-
- if (c != 0x00 && c != 0xE0)
- return c;
- else
- switch (getch ())
- {
- case 71:
- /* Home. */
- return 'b';
-
- case 73:
- /* Page up. */
- case 83:
- /* Del. */
- return 0177;
-
- case 81:
- /* Page down. */
- default:
- return ' ';
- }
- }
-
-
- /*
- * Local Variables:
- * mode:C
- * ChangeLog:ChangeLog
- * compile-command:make
- * End:
- */
-