Annotation of coherent/d/usr/bin/elvis/pc.c, revision 1.1.1.1

1.1       root        1: /* pc.c */
                      2: 
                      3: /* Author:
                      4:  *     Guntram Blohm
                      5:  *     Buchenstrasse 19
                      6:  *     7904 Erbach, West Germany
                      7:  *     Tel. ++49-7305-6997
                      8:  *     sorry - no regular network connection
                      9:  */
                     10: 
                     11: /* This file implements the ibm pc bios interface. See IBM documentation
                     12:  * for details.
                     13:  * If TERM is set upon invocation of elvis, this code is ignored completely,
                     14:  * and the standard termcap functions are used, thus, even not-so-close
                     15:  * compatibles can run elvis. For close compatibles however, bios output
                     16:  * is much faster (and permits reverse scrolling, adding and deleting lines,
                     17:  * and much more ansi.sys isn't capable of). GB.
                     18:  */
                     19: 
                     20: #include "config.h"
                     21: #include "vi.h"
                     22: 
                     23: #if MSDOS
                     24: 
                     25: #include <dos.h>
                     26: 
                     27: static void video();
                     28: 
                     29: /* vmode contains the screen attribute index and is set by attrset.*/
                     30: 
                     31: int vmode;
                     32: 
                     33: /* The following array contains attribute definitions for
                     34:  * color/monochrome attributes. Screen selects one of the sets.
                     35:  * Maybe i'll put them into elvis options one day.
                     36:  */
                     37: 
                     38: static int screen;
                     39: static char attr[2][5] =
                     40: {
                     41:        /*      :se:    :so:    :VB:    :ul:    :as:    */
                     42:        {       0x17,   0x1d,   0x1e,   0x1a,   0x1c,   },      /* color */
                     43:        {       0x07,   0x70,   0x0f,   0x01,   0x0f,   },      /* monochrome */
                     44: };
                     45: 
                     46: /*
                     47:  * bios interface functions for elvis - pc version
                     48:  */
                     49: 
                     50: /* cursor up: determine current position, decrement row, set position */
                     51: 
                     52: void v_up()
                     53: {
                     54:        int dx;
                     55:        video(0x300,(int *)0,&dx);
                     56:        dx-=0x100;
                     57:        video(0x200,(int *)0,&dx);
                     58: }
                     59: 
                     60: #ifndef NO_CURSORSHAPE
                     61: /* cursor big: set begin scan to end scan - 4 */
                     62: void v_cb()
                     63: {
                     64:        int cx;
                     65:        video(0x300, &cx, (int *)0);
                     66:        cx=((cx&0xff)|(((cx&0xff)-4)<<8));
                     67:        video(0x100, &cx, (int *)0);
                     68: }
                     69: 
                     70: /* cursor small: set begin scan to end scan - 1 */
                     71: void v_cs()
                     72: {
                     73:        int cx;
                     74:        video(0x300, &cx, (int *)0);
                     75:        cx=((cx&0xff)|(((cx&0xff)-1)<<8));
                     76:        video(0x100, &cx, (int *)0);
                     77: }
                     78: #endif
                     79: 
                     80: /* clear to end: get cursor position and emit the aproppriate number
                     81:  * of spaces, without moving cursor.
                     82:  */
                     83:  
                     84: void v_ce()
                     85: {
                     86:        int cx, dx;
                     87:        video(0x300,(int *)0,&dx);
                     88:        cx=COLS-(dx&0xff);
                     89:        video(0x920,&cx,(int *)0);
                     90: }
                     91: 
                     92: /* clear screen: clear all and set cursor home */
                     93: 
                     94: void v_cl()
                     95: {
                     96:        int cx=0, dx=((LINES-1)<<8)+COLS-1;
                     97:        video(0x0600,&cx,&dx);
                     98:        dx=0;
                     99:        video(0x0200,&cx,&dx);
                    100: }
                    101: 
                    102: /* clear to bottom: get position, clear to eol, clear next line to end */
                    103: 
                    104: void v_cd()
                    105: {
                    106:        int cx, dx, dxtmp;
                    107:        video(0x0300,(int *)0,&dx);
                    108:        dxtmp=(dx&0xff00)|(COLS-1);
                    109:        cx=dx;
                    110:        video(0x0600,&cx,&dxtmp);
                    111:        cx=(dx&0xff00)+0x100;
                    112:        dx=((LINES-1)<<8)+COLS-1;
                    113:        video(0x600,&cx,&dx);
                    114: }
                    115: 
                    116: /* add line: scroll rest of screen down */
                    117: 
                    118: void v_al()
                    119: {
                    120:        int cx,dx;
                    121:        video(0x0300,(int *)0,&dx);
                    122:        cx=(dx&0xff00);
                    123:        dx=((LINES-1)<<8)+COLS-1;
                    124:        video(0x701,&cx,&dx);
                    125: }
                    126: 
                    127: /* delete line: scroll rest up */
                    128: 
                    129: void v_dl()
                    130: {
                    131:        int cx,dx;
                    132:        video(0x0300,(int *)0,&dx);
                    133:        cx=(dx&0xff00)/*+0x100*/;
                    134:        dx=((LINES-1)<<8)+COLS-1;
                    135:        video(0x601,&cx,&dx);
                    136: }
                    137: 
                    138: /* scroll reverse: scroll whole screen */
                    139: 
                    140: void v_sr()
                    141: {
                    142:        int cx=0, dx=((LINES-1)<<8)+COLS-1;
                    143:        video(0x0701,&cx,&dx);
                    144: }
                    145: 
                    146: /* set cursor */
                    147: 
                    148: void v_move(x,y)
                    149:        int x, y;
                    150: {
                    151:        int dx=(y<<8)+x;
                    152:        video(0x200,(int *)0,&dx);
                    153: }
                    154: 
                    155: /* put character: set attribute first, then execute char.
                    156:  * Also remember if current line has changed.
                    157:  */
                    158: 
                    159: int v_put(ch)
                    160:        int ch;
                    161: {
                    162:        int cx=1;
                    163:        ch&=0xff;
                    164:        if (ch>=' ')
                    165:                video(0x900|ch,&cx,(int *)0);
                    166:        video(0xe00|ch,(int *)0, (int *)0);
                    167:        if (ch=='\n')
                    168:        {       exwrote = TRUE;
                    169:                video(0xe0d, (int *)0, (int *)0);
                    170:        }
                    171:        return ch;
                    172: }
                    173: 
                    174: /* determine number of screen columns. Also set attrset according
                    175:  * to monochrome/color screen.
                    176:  */
                    177: 
                    178: int v_cols()
                    179: {
                    180:        union REGS regs;
                    181:        regs.h.ah=0x0f;
                    182:        int86(0x10, &regs, &regs);
                    183:        if (regs.h.al==7)                       /* monochrome mode ? */
                    184:                screen=1;
                    185:        else
                    186:                screen=0;
                    187:        return regs.h.ah;
                    188: }
                    189: 
                    190: /* Getting the number of rows is hard. Most screens support 25 only,
                    191:  * EGA/VGA also support 43/50 lines, and some OEM's even more.
                    192:  * Unfortunately, there is no standard bios variable for the number
                    193:  * of lines, and the bios screen memory size is always rounded up
                    194:  * to 0x1000. So, we'll really have to cheat.
                    195:  * When using the screen memory size, keep in mind that each character
                    196:  * byte has an associated attribute byte.
                    197:  *
                    198:  * uses:       word at 40:4c contains  memory size
                    199:  *             byte at 40:84           # of rows-1 (sometimes)
                    200:  *             byte at 40:4a           # of columns
                    201:  */
                    202: 
                    203: int v_rows()
                    204: {
                    205:        int line, oldline;
                    206: 
                    207:        /* screen size less then 4K? then we have 25 lines only */
                    208: 
                    209:        if (*(int far *)(0x0040004cl)<=4096)
                    210:                return 25;
                    211: 
                    212:        /* VEGA vga uses the bios byte at 0x40:0x84 for # of rows.
                    213:         * Use that byte, if it makes sense together with memory size.
                    214:         */
                    215: 
                    216:        if ((((*(unsigned char far *)(0x0040004aL)*2*
                    217:                (*(unsigned char far *)(0x00400084L)+1))+0xfff)&(~0xfff))==
                    218:                *(unsigned int far *)(0x0040004cL))
                    219:                        return *(unsigned char far *)(0x00400084L)+1;
                    220: 
                    221:        /* uh oh. Emit '\n's until screen starts scrolling. */
                    222: 
                    223:        v_move(oldline=0, 0);
                    224:        for (;;)
                    225:        {
                    226:                video(0xe0a,(int *)0,(int *)0);
                    227:                video(0x300,(int *)0,&line);
                    228:                line>>=8;
                    229:                if (oldline==line)
                    230:                        return line+1;
                    231:                oldline=line;   
                    232:        }
                    233: }
                    234: 
                    235: /* the REAL bios interface -- used internally only. */
                    236: 
                    237: static void video(ax, cx, dx)
                    238:        int ax, *cx, *dx;
                    239: {
                    240:        union REGS regs;
                    241: 
                    242:        regs.x.ax=ax;
                    243:        if ((ax&0xff00)==0x600 || (ax&0xff00)==0x700)
                    244:                regs.h.bh=attr[screen][vmode];
                    245:        else
                    246:        {
                    247:                regs.h.bh=0;
                    248:                regs.h.bl=attr[screen][vmode];
                    249:        }
                    250:        if (cx) regs.x.cx=*cx;
                    251:        if (dx) regs.x.dx=*dx;
                    252:        int86(0x10, &regs, &regs);
                    253:        if (dx) *dx=regs.x.dx;
                    254:        if (cx) *cx=regs.x.cx;
                    255: }
                    256: 
                    257: /* The following function determines which character is used for
                    258:  * commandline-options by command.com. This system call is undocumented
                    259:  * and valid for versions < 4.00 only.
                    260:  */
                    261:  
                    262: int switchar()
                    263: {
                    264:        union REGS regs;
                    265:        regs.x.ax=0x3700;
                    266:        int86(0x21, &regs, &regs);
                    267:        return regs.h.dl;
                    268: }
                    269: 
                    270: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.