Annotation of coherent/d/usr/bin/elvis/pc.c, revision 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.