|
|
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, ®s, ®s); ! 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, ®s, ®s); ! 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, ®s, ®s); ! 267: return regs.h.dl; ! 268: } ! 269: ! 270: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.