/* Copyright (C) Magna Carta Software, Inc. 1990. All Rights Reserved C COMMUNICATIONS TOOLKIT CURSOR.C -- raw screen cursor routines (INT 10H) to support emulations. These functions use the BIOS to support full-screen terminal cursor operations. */ #define CCT_DEVELOPMENT #include #include #include #include #include #include #define VIDEO 0X10 #define BIOS_CRT_MODE 0X449 #define BIOS_CRT_COLS 0X44A #define BIOS_CRT_LEN 0X44C #define BIOS_CCOL 0X450 /* BIOS record of cursor column */ #define BIOS_CROW 0X451 /* BIOS record of cursor row */ #define BIOS_CRT_ROWS 0X484 static WORD crt_cols, crt_rows, cur_top, cur_bottom; /* BIOS_VIDEO -- Set up pointers to functions that perform video output under terminal emulation. Arguments: TERMINAL *t -- the terminal structure; */ void bios_video(TERMINAL *t) { crt_cols = bios_get_crt_cols(t); crt_rows = bios_get_crt_rows(t); t->con_get = bios_get; /* do console screen input at row, col */ t->con_put = bios_put; /* do console output at row, col */ t->con_putc = bios_putc; /* do console output at cursor */ t->cur_get_col = bios_cur_get_col; t->cur_get_row = bios_cur_get_row; t->ccol = (*t->cur_get_col)(t); t->crow = (*t->cur_get_row)(t); t->csize = bios_cur_get_size(t); t->cur_pos_ = bios_cur_pos; t->cur_size_ = bios_cur_size; t->ebd = bios_ebd; /* erase from beginning of display */ t->ebl = bios_ebl; /* erase to end of line */ t->ech = bios_ech; /* erase characters */ t->ed = bios_ed; /* erase display */ t->eed = bios_eed; /* erase to end of display */ t->eel = bios_eel; /* erase from beginning of line */ t->eil = bios_eil; /* erase in line */ t->scroll = bios_scroll; } /* BIOS_CUR_GET_COL -- Return the current column of the cursor on video page zero. */ WORD bios_cur_get_col(TERMINAL *t) { return (peekb(0, BIOS_CCOL)); } /* BIOS_CUR_GET_ROW -- Return the current row of the cursor on video page zero. */ WORD bios_cur_get_row(TERMINAL *t) { return (peekb(0, BIOS_CROW)); } /* BIOS_CUR_POS -- positions the cursor on the specified page. */ void bios_cur_pos(TERMINAL *t, short col, short row) { union REGS regs; setbytereg(ah) = 2; /* set cursor position */ setbytereg(bh) = '\0'; /* video page */ setbytereg(dh) = (BYTE) row; /* row # */ setbytereg(dl) = (BYTE) col; /* column # */ int86(VIDEO, ®s, ®s); } /* BIOS_CUR_GET_SIZE -- Get the cursor size on the active page. */ short bios_cur_get_size(TERMINAL *t) { union REGS regs; setbytereg(ah) = 3; /* request cursor size */ setbytereg(bh) = 0; /* from the active page */ int86(VIDEO, ®s, ®s); /* ROM BIOS video service */ cur_top = setbytereg(ch); /* top line of cursor */ cur_bottom = setbytereg(cl); /* bottom line of cursor */ return (setwordreg(cx)); /* combine for return */ } /* BIOS_CUR_SIZE -- sets the cursor size. top_line=bottom_line=0 turns it off. */ void bios_cur_size(TERMINAL *t, WORD size) { union REGS regs; BYTE top_line = (BYTE) (size >> 8); BYTE bot_line = (BYTE) (size & 0XFF); setbytereg(ah) = 1; /* BIOS function 1, set cursor size */ if (top_line == 0 && bot_line == 0) { setwordreg(cx) = 0X2100; /* request cursor off */ int86(VIDEO, ®s, ®s); } else { setbytereg(ch) = top_line; /* row */ setbytereg(cl) = bot_line; /* column */ int86(VIDEO, ®s, ®s); } } /* BIOS_EBL -- Clear from the beginning of the line to the current cursor position. MSC 6.00A gives an erroneous warning that "conditional expressions is constant" when compiling the "for" loop below. */ void bios_ebl(TERMINAL *t, short ch, WORD att) { WORD i, row, col; col = bios_cur_get_col(t); row = bios_cur_get_row(t); bios_cur_pos(t, 0, row); for (i=0; i <= col; i++) { bios_cur_pos(t, i, row); bios_putc(t, ch, att); } bios_cur_pos(t, col, row); } /* BIOS_EBD -- Clear from the beginning of the display up to and including the current cursor position. */ void bios_ebd(TERMINAL *t, short ch, WORD att) { WORD row; row = bios_cur_get_row(t); if (row) { bios_scroll(t, 0, 0, crt_cols - 1, row - 1, att, 0); } bios_ebl(t, ch, att); } /* BIOS_ECH -- Delete 'num' characters from a line and fill with remaining characters. */ void bios_ech(TERMINAL *t, short ch, WORD att, short num) { short row, ch1, i, col; col = bios_cur_get_col(t); /* preserve cursor position */ row = bios_cur_get_row(t); for (i=col+num; i < (short) crt_cols; i++) { bios_cur_pos(t, i, row); /* go to character to move */ ch1 = bios_getc(t); /* get it */ bios_cur_pos(t, i-num, row); /* go back to where we write ch */ bios_putc(t, ch1 & 0XFF, att); /* write it */ } for (i=0; i 50) ret = 25; else ret = peekb(0, BIOS_CRT_ROWS) + 1; crt_rows = ret; return (ret); } /* BIOS_GETC -- Read a character from the screen. */ short bios_getc(TERMINAL *t) { union REGS regs; setwordreg(ax) = 0X0800; setbytereg(bh) = 0; int86(VIDEO,®s,®s); return (setwordreg(ax)); } /* BIOS_PUT -- ANSI fn. to write a character on the screen. This function is pointed to by p->c_out and replaces fputc(). */ short bios_put(TERMINAL *t, short col, short row, short ch, WORD att) { short scol, srow; scol = bios_cur_get_col(t); srow = bios_cur_get_row(t); bios_cur_pos(t, col, row); bios_putc(t, ch, att); bios_cur_pos(t, scol, srow); return (0); } /* BIOS_PUTC -- ANSI fn. to write a character on the screen at the cursor location. This function is pointed to by p->con_out and replaces fputc(). */ short bios_putc(TERMINAL *t, short ch, short att) { union REGS regs; setwordreg(ax) = 0X0900 | (BYTE) ch; setwordreg(bx) = att & 0XFF; setwordreg(cx) = 1; int86(VIDEO,®s,®s); return (0); } /* BIOS_SCROLL -- scrolls up or down the designated number of lines. */ void bios_scroll(TERMINAL *t, WORD tlc, WORD tlr, WORD brc, WORD brr, WORD att, short count) { union REGS regs; setbytereg(ah) = (BYTE) (6 + ((count > 0) ? 0 : 1)); /* select service */ setbytereg(al) = (BYTE) ((count > 0) ? count : -count); /* # of lines to scroll */ setbytereg(bh) = (BYTE) att; /* display att. for blanks */ setwordreg(cx) = (tlr << 8) | (tlc); /* upper left coords. */ setwordreg(dx) = (brr << 8) | (brc); /* lower right coords. */ int86(VIDEO, ®s, ®s); } /* CUR_OFF -- Turn the cursor off. */ void cur_off(TERMINAL *t) { union REGS regs; setbytereg(ah) = 1; setwordreg(cx) = 0X2100; /* request cursor off */ int86(VIDEO, ®s, ®s); } /* CUR_ON -- Turn the cursor on. */ void cur_on(TERMINAL *t) { union REGS regs; setbytereg(ah) = 1; setbytereg(ch) = (BYTE) cur_top; /* row */ setbytereg(cl) = (BYTE) cur_bottom; /* column */ int86(VIDEO, ®s, ®s); }